Skip to content

Commit 7974d47

Browse files
committed
added PropertiesUtils EncodeUtils.encodeUnicode
1 parent 73dd0c5 commit 7974d47

File tree

3 files changed

+241
-1
lines changed

3 files changed

+241
-1
lines changed

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

src/main/kotlin/cn/imkarl/core/common/encode/EncodeUtils.kt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import java.net.URLDecoder
66
import java.net.URLEncoder
77
import java.nio.charset.Charset
88
import java.util.*
9+
import java.util.regex.Pattern
910

1011
/**
1112
* 编解码相关工具类
@@ -19,6 +20,8 @@ object EncodeUtils {
1920
val UTF_16LE = Charset.forName("UTF-16LE")
2021
val UTF_16 = Charset.forName("UTF-16")
2122

23+
private val PATTERN_UNICODE = Pattern.compile("\\\\u([0-9A-Fa-f]{4})")
24+
2225

2326
/**
2427
* Base64编码
@@ -87,6 +90,77 @@ object EncodeUtils {
8790
}
8891

8992

93+
/**
94+
* Unicode编码
95+
*
96+
* @param data 待编码的字符
97+
* @return 编码结果,若编码失败则直接将data原样返回
98+
*/
99+
@JvmStatic
100+
fun encodeUnicode(data: String?): String? {
101+
if (data == null) {
102+
return null
103+
}
104+
if (data.isBlank()) {
105+
return ""
106+
}
107+
108+
val unicodeBytes = StringBuilder()
109+
for (ch in data.toCharArray()) {
110+
if (ch.toInt() < 10) {
111+
unicodeBytes.append("\\u000").append(Integer.toHexString(ch.toInt()))
112+
continue
113+
}
114+
115+
if (Character.UnicodeBlock.of(ch) === Character.UnicodeBlock.BASIC_LATIN) {
116+
// 英文及数字等
117+
unicodeBytes.append(ch)
118+
} else {
119+
// to Unicode
120+
val hex = Integer.toHexString(ch.toInt())
121+
if (hex.length == 1) {
122+
unicodeBytes.append("\\u000").append(hex)
123+
} else if (hex.length == 2) {
124+
unicodeBytes.append("\\u00").append(hex)
125+
} else if (hex.length == 3) {
126+
unicodeBytes.append("\\u0").append(hex)
127+
} else if (hex.length == 4) {
128+
unicodeBytes.append("\\u").append(hex)
129+
}
130+
}
131+
}
132+
return unicodeBytes.toString()
133+
}
134+
135+
/**
136+
* Unicode解码
137+
*
138+
* @param data 待解码的字符
139+
* @return 解码结果,若解码失败则直接将data原样返回
140+
*/
141+
@JvmStatic
142+
fun decodeUnicode(data: String?): String? {
143+
if (data == null) {
144+
return null
145+
}
146+
if (!data.contains("\\u")) {
147+
return data
148+
}
149+
150+
val buf = StringBuffer()
151+
val matcher = PATTERN_UNICODE.matcher(data)
152+
while (matcher.find()) {
153+
try {
154+
matcher.appendReplacement(buf, "")
155+
buf.appendCodePoint(Integer.parseInt(matcher.group(1), 16))
156+
} catch (ignored: NumberFormatException) {
157+
}
158+
}
159+
matcher.appendTail(buf)
160+
return buf.toString()
161+
}
162+
163+
90164
/**
91165
* 字节数组转16进制字符串
92166
*
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package cn.imkarl.core.common.file
2+
3+
import cn.imkarl.core.common.json.JsonUtils
4+
import java.io.File
5+
import java.util.*
6+
import kotlin.properties.ReadWriteProperty
7+
import kotlin.reflect.KProperty
8+
9+
/**
10+
* Properties工具类
11+
* @author imkarl
12+
*/
13+
class PropertiesUtils(private val file: File) {
14+
15+
private val properties: Properties
16+
17+
init {
18+
if (!file.exists()) {
19+
FileUtils.createNewFile(file)
20+
}
21+
properties = Properties()
22+
properties.load(file.inputStream())
23+
}
24+
25+
fun getString(key: String): String? {
26+
return getString(key, null)
27+
}
28+
fun getString(key: String, defValue: String?): String? {
29+
return properties.getProperty(key, defValue)
30+
}
31+
32+
inline fun <reified T> get(key: String, defValue: T): T {
33+
val value = getString(key)
34+
if (value.isNullOrBlank()) {
35+
return defValue
36+
}
37+
38+
return when(T::class) {
39+
String::class -> getString(key) ?: defValue
40+
Boolean::class -> getString(key)?.toBoolean() ?: defValue
41+
Double::class -> getString(key)?.toDoubleOrNull() ?: defValue
42+
Float::class -> getString(key)?.toFloatOrNull() ?: defValue
43+
Int::class -> getString(key)?.toIntOrNull() ?: defValue
44+
Long::class -> getString(key)?.toLongOrNull() ?: defValue
45+
else -> try { JsonUtils.fromJson<T>(getString(key)) } catch (throwable: Throwable) { defValue }
46+
} as T
47+
}
48+
49+
50+
51+
/**
52+
* 获取Editor
53+
*/
54+
fun edit(): Editor {
55+
return Editor(properties, file)
56+
}
57+
58+
/**
59+
* 保存数据
60+
*/
61+
fun put(key: String, value: Any?) {
62+
edit().put(key, value).commit()
63+
}
64+
65+
/**
66+
* 是否保存key
67+
*
68+
* @param key 键
69+
* @return 是否保存过
70+
*/
71+
operator fun contains(key: String): Boolean {
72+
return key.isNotEmpty() && properties.contains(key)
73+
}
74+
75+
/**
76+
* 删除数据
77+
*/
78+
fun remove(key: String) {
79+
if (key.isEmpty()) {
80+
return
81+
}
82+
edit().remove(key).commit()
83+
}
84+
85+
/**
86+
* 清空所有数据
87+
*/
88+
fun clear() {
89+
edit().clear().commit()
90+
}
91+
92+
93+
inline fun <reified T> field(defValue: T): ReadWriteProperty<Any, T> {
94+
return object: ReadWriteProperty<Any, T> {
95+
override fun getValue(thisRef: Any, property: KProperty<*>): T {
96+
val key = property.name
97+
return get(key, defValue)
98+
}
99+
100+
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
101+
val key = property.name
102+
when(T::class) {
103+
String::class, Boolean::class, Double::class, Float::class, Int::class, Long::class -> put(key, value)
104+
else -> put(key, value?.let { JsonUtils.toJson(value) })
105+
}
106+
}
107+
}
108+
}
109+
inline fun <reified T> fieldByKey(key: String, defValue: T): ReadWriteProperty<Any, T> {
110+
return object: ReadWriteProperty<Any, T> {
111+
override fun getValue(thisRef: Any, property: KProperty<*>): T {
112+
return get(key, defValue)
113+
}
114+
115+
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
116+
when(T::class) {
117+
String::class, Boolean::class, Double::class, Float::class, Int::class, Long::class -> put(key, value)
118+
else -> put(key, value?.let { JsonUtils.toJson(value) })
119+
}
120+
}
121+
}
122+
}
123+
124+
inner class Editor internal constructor(private val properties: Properties, private val file: File) {
125+
/**
126+
* 保存数据
127+
*/
128+
fun put(key: String, value: Any?): Editor {
129+
if (key.isEmpty()) {
130+
return this
131+
}
132+
if (value == null) {
133+
return remove(key)
134+
}
135+
136+
properties.setProperty(key, value.toString())
137+
return this
138+
}
139+
140+
/**
141+
* 删除数据
142+
*/
143+
fun remove(key: String): Editor {
144+
if (key.isNotEmpty()) {
145+
properties.remove(key)
146+
}
147+
return this
148+
}
149+
150+
/**
151+
* 清空所有数据
152+
*/
153+
fun clear(): Editor {
154+
properties.clear()
155+
return this
156+
}
157+
158+
/**
159+
* 提交修改
160+
*/
161+
fun commit() {
162+
properties.store(file.outputStream(), null)
163+
}
164+
}
165+
166+
}

0 commit comments

Comments
 (0)