mirror of https://github.com/nitu2003/T18n
Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
Taskeren | bf55d38a7b | |
Taskeren | 1625253fca | |
Taskeren | b9d5915cda | |
倪钍 | 7e91fa3d4c | |
Taskeren | d87eb146d4 | |
Taskeren | 240bc0cd0b | |
Taskeren | 355f64b475 | |
Taskeren | add75a4059 | |
Taskeren | f02dbeabc1 | |
Taskeren | 009699b11e | |
Taskeren | 4eef26a4c8 | |
Taskeren | b4fa3f0fd0 | |
Taskeren | 4b01a2e58d |
18
.classpath
18
.classpath
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
|
@ -0,0 +1,17 @@
|
|||
name: Java CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
|
@ -3,3 +3,9 @@
|
|||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
||||
|
||||
# eclipse
|
||||
bin/
|
||||
.settings/
|
||||
.classpath
|
||||
.project
|
23
.project
23
.project
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>T18n</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,2 +0,0 @@
|
|||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
|
@ -1,13 +0,0 @@
|
|||
#
|
||||
#Tue Jun 25 20:09:41 CST 2019
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
@ -0,0 +1,82 @@
|
|||
<h1 align="center">
|
||||
Taskeren's Internationalization
|
||||
</h1>
|
||||
|
||||
<h4 align="center">
|
||||
A lightweight, powerful I18n tool for Java.
|
||||
</h4>
|
||||
|
||||
## Get T18n
|
||||
|
||||
You can get this project in Jitpack with Maven, Gradle and so on.
|
||||
|
||||
### Maven
|
||||
|
||||
1. Import the Jitpack source.
|
||||
```
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
|
||||
2. Add the denpendency.
|
||||
```
|
||||
<dependency>
|
||||
<groupId>com.github.nitu2003</groupId>
|
||||
<artifactId>T18n</artifactId>
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Gradle
|
||||
|
||||
1. Import the Jitpack source.
|
||||
```
|
||||
repositories {
|
||||
...
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
```
|
||||
|
||||
2. Add the dependency.
|
||||
```
|
||||
dependencies {
|
||||
implementation 'com.github.nitu2003:T18n:1.5'
|
||||
}
|
||||
```
|
||||
|
||||
### For else
|
||||
[![](https://jitpack.io/v/nitu2003/T18n.svg)](https://jitpack.io/#nitu2003/T18n)
|
||||
|
||||
## Dev with T18n
|
||||
|
||||
1. Get the Language Map.
|
||||
```java
|
||||
// from file
|
||||
LanguageMapBuilder.fromFile(new File("res/i18n/en_us.lang"));
|
||||
// from jar resource
|
||||
LanguageMapBuilder.fromJarResource("res/i18n/en_us.lang");
|
||||
// from online content (Deprecated)
|
||||
LanguageMapBuilder.fromURL("https://example.com/i18n/en.lang");
|
||||
```
|
||||
|
||||
2. Push it to the I18n.
|
||||
```java
|
||||
// reset the I18n and push it
|
||||
T18n.set(theMap);
|
||||
// add the new to the old
|
||||
T18n.add(theMap);
|
||||
```
|
||||
|
||||
3. Use it in the project
|
||||
_en.lang_
|
||||
```
|
||||
HelloToUser=Hello %s.
|
||||
```
|
||||
_app.java_
|
||||
```java
|
||||
System.out.println(I18n.format("HelloToUser", "Taskeren")); // It should be "Hello Taskeren"
|
||||
```
|
|
@ -1,2 +0,0 @@
|
|||
/main/
|
||||
/test/
|
|
@ -4,21 +4,28 @@ import java.nio.charset.Charset;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class I18n {
|
||||
|
||||
private static LanguageMap map;
|
||||
private static Charset charset;
|
||||
protected static LanguageMap map;
|
||||
protected static Charset charset;
|
||||
|
||||
protected static final int LOOP_MAX_COUNT = 32767;
|
||||
|
||||
static {
|
||||
map = new LanguageMap();
|
||||
charset = Charset.forName(System.getProperty("file.encoding"));
|
||||
}
|
||||
|
||||
public static void setLanguageMap(LanguageMap map) {
|
||||
I18n.map = map;
|
||||
}
|
||||
/* *******************************************************
|
||||
*
|
||||
* Localization functions
|
||||
*
|
||||
* *******************************************************/
|
||||
|
||||
public static void setEncoding(String charset) {
|
||||
I18n.charset = Charset.forName(charset);
|
||||
/** 自动从语言文件中提取翻译,空翻译时返回原键值 */
|
||||
protected static String translate(String key) {
|
||||
return reEncode(map.get(key), charset);
|
||||
}
|
||||
|
||||
/** 自动翻译(translate)后再执行格式化(format) */
|
||||
|
@ -28,24 +35,19 @@ public class I18n {
|
|||
format);
|
||||
}
|
||||
|
||||
/** 自动从语言文件中提取翻译,空翻译时返回原键值 */
|
||||
public static String translate(String key) {
|
||||
return reEncode(getLanguageMapSafe().get(key), charset);
|
||||
}
|
||||
|
||||
/** 自动翻译(translate)列表,将多行替换为一行后再执行格式化(format)<br>
|
||||
* @param key 进入列表的格式化代码(format key),例如<code>app.message.welcome.%s</code>,其中<code>%s</code>会被替换为从<code>0</code>开始的数字,逐行读取,直到空翻译或最大值(1000)
|
||||
/**
|
||||
* 连续读取翻译(translate)。
|
||||
* @param keyRegular 翻译键值表达式,需要填入一个“%s”用于替换为行数。行数从0开始。例如“welcome.%s”,则程序会依次向列表中添加“welcome.0”,“welcome.1”...的翻译,直到获取到空值。
|
||||
*/
|
||||
public static String format2(String key, Object...format) {
|
||||
protected static List<String> translateList(String keyRegular) {
|
||||
|
||||
List<String> vlist = new ArrayList<String>();
|
||||
|
||||
int i = 0;
|
||||
int max = 1000;
|
||||
|
||||
while(true) {
|
||||
if(i >= max) break;
|
||||
String k = tryFormat(key, i);
|
||||
if(i >= LOOP_MAX_COUNT) break;
|
||||
String k = tryFormat(keyRegular, i);
|
||||
if(hasKey(k)) {
|
||||
vlist.add(translate(k));
|
||||
} else {
|
||||
|
@ -54,28 +56,32 @@ public class I18n {
|
|||
i++;
|
||||
}
|
||||
|
||||
String v = "";
|
||||
for(String o : vlist) {
|
||||
v += o + "\n";
|
||||
}
|
||||
v = v.trim();
|
||||
return vlist;
|
||||
|
||||
v = tryFormat(v, format);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将列表翻译中的内容进行format操作。
|
||||
* @see #translateList(String)
|
||||
*/
|
||||
public static String formatList(String keyRegular, Object...format) {
|
||||
|
||||
return tryFormat(T18nUtils.flattenList(translateList(keyRegular)), format);
|
||||
|
||||
}
|
||||
|
||||
public static boolean hasKey(String key) {
|
||||
return getLanguageMapSafe().containsKey(key);
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public static boolean canTranslate(String key) {
|
||||
return hasKey(key);
|
||||
}
|
||||
/* *******************************************************
|
||||
*
|
||||
* Utilities
|
||||
*
|
||||
* *******************************************************/
|
||||
|
||||
private static String reEncode(String bef, Charset charset) {
|
||||
byte[] bytes = bef.getBytes();
|
||||
byte[] bytes = bef.getBytes(charset);
|
||||
return new String(bytes, charset);
|
||||
}
|
||||
|
||||
|
@ -87,8 +93,4 @@ public class I18n {
|
|||
}
|
||||
}
|
||||
|
||||
private static LanguageMap getLanguageMapSafe() {
|
||||
return map == null ? new LanguageMap() : map;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,112 +6,149 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LanguageMapBuilder {
|
||||
|
||||
/**
|
||||
* 从文件读取语言包
|
||||
* @param langFile 语言文件
|
||||
* @return 语言包
|
||||
*/
|
||||
public static LanguageMap fromFile(File langFile) {
|
||||
return fromFile(langFile, LanguageMapConfiguration.DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从文件读取语言包
|
||||
* @param langFile 语言文件
|
||||
* @param config 读取配置
|
||||
* @return 语言包
|
||||
*/
|
||||
public static LanguageMap fromFile(File langFile, LanguageMapConfiguration config) {
|
||||
|
||||
List<String> lines = getLinesFromFile(langFile);
|
||||
return getLanguageMapFromLines(config, lines);
|
||||
}
|
||||
|
||||
private static List<String> getLinesFromFile(File file) {
|
||||
if(file.isFile()) {
|
||||
try {
|
||||
return Files.readAllLines(file.toPath(), Charset.forName("UTF-8"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private static LanguageMap getLanguageMapFromLines(LanguageMapConfiguration config, List<String> lines) {
|
||||
|
||||
final LanguageMap map = new LanguageMap();
|
||||
|
||||
for(String s : lines) {
|
||||
String[] pair = getLanguageMapFromLine(config, s);
|
||||
if(!isUnreadable(pair)) {
|
||||
map.put(pair[0], pair[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
private static final String[] UNREADABLE = new String[] {null, null};
|
||||
|
||||
private static String[] getLanguageMapFromLine(LanguageMapConfiguration config, String s) {
|
||||
|
||||
/* Empty Line */
|
||||
if(s == null || s.length() == 0) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
/* Annotation */
|
||||
if(config.isAnnotation(s)) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
String[] parts = s.split(config.getSplitter(s), 2);
|
||||
|
||||
/* The Key is Null */
|
||||
if(parts[0] == null || parts[0].length() == 0) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
/* The Value is Null */
|
||||
if(parts[1] == null) {
|
||||
parts[1] = "null";
|
||||
}
|
||||
|
||||
return parts;
|
||||
|
||||
}
|
||||
|
||||
private static boolean isUnreadable(String[] s) {
|
||||
return s[0] == null;
|
||||
}
|
||||
|
||||
public static LanguageMap fromJarResource(String path) {
|
||||
return fromJarResource(path, LanguageMapConfiguration.DEFAULT);
|
||||
|
||||
List<String> lines = T18nUtils.getLocalContent(langFile);
|
||||
return processFinal(config, lines);
|
||||
}
|
||||
|
||||
public static LanguageMap fromJarResource(String path, LanguageMapConfiguration config) {
|
||||
|
||||
/**
|
||||
* 以 UTF8 为编码读取Jar包里的资源
|
||||
* @param path 资源地址
|
||||
* @return 语言包
|
||||
*/
|
||||
public static LanguageMap fromJarResource(String path) {
|
||||
return fromJarResource(path, "UTF8", LanguageMapConfiguration.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用设定编码读取Jar包里的资源
|
||||
* @param path 资源地址
|
||||
* @param encode 编码名称,例如<code>UTF-8</code>,<code>GBK</code>,<code>Unicode</code>等等。
|
||||
* @param config 读取配置
|
||||
* @return 语言包
|
||||
*/
|
||||
public static LanguageMap fromJarResource(String path, String encode, LanguageMapConfiguration config) {
|
||||
|
||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
|
||||
if(is == null) {
|
||||
if (is == null) {
|
||||
return new LanguageMap();
|
||||
}
|
||||
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is, Charset.forName(encode)));
|
||||
|
||||
String cache;
|
||||
List<String> strs = new ArrayList<>();
|
||||
|
||||
|
||||
try {
|
||||
while(true) {
|
||||
if((cache = br.readLine()) != null) {
|
||||
while (true) {
|
||||
if ((cache = br.readLine()) != null) {
|
||||
strs.add(cache);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
return getLanguageMapFromLines(config, strs);
|
||||
|
||||
|
||||
return processFinal(config, strs);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从在线页面读取语言包
|
||||
* @param url 页面地址
|
||||
* @return 语言包
|
||||
*/
|
||||
public static LanguageMap fromURL(String url) {
|
||||
return fromURL(url, LanguageMapConfiguration.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从在线页面读取语言包
|
||||
* @param url 页面地址
|
||||
* @param config 读取配置
|
||||
* @return 语言包
|
||||
*/
|
||||
public static LanguageMap fromURL(String url, LanguageMapConfiguration config) {
|
||||
return processFinal(config, T18nUtils.getOnlineContent(url));
|
||||
}
|
||||
|
||||
private static final String[] UNREADABLE = new String[] { null, null };
|
||||
|
||||
/** 处理单行翻译 */
|
||||
private static String[] process(LanguageMapConfiguration config, String s) {
|
||||
|
||||
/* Empty Line */
|
||||
if (s == null || s.length() == 0) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
/* Annotation */
|
||||
if (config.isAnnotation(s)) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
String[] parts = s.split(config.getSplitter(s), 2);
|
||||
|
||||
/* Part fewer than 2 */
|
||||
if(parts.length < 2) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
/* The Key is Null */
|
||||
if (parts[0] == null || parts[0].length() == 0) {
|
||||
return UNREADABLE;
|
||||
}
|
||||
|
||||
/* The Value is Null */
|
||||
if (parts[1] == null) {
|
||||
parts[1] = "null";
|
||||
}
|
||||
|
||||
return parts;
|
||||
|
||||
}
|
||||
|
||||
private static boolean isUnreadable(String[] s) {
|
||||
return s[0] == null;
|
||||
}
|
||||
|
||||
/** 将处理的结果整合到翻译表中 */
|
||||
private static LanguageMap processFinal(LanguageMapConfiguration config, List<String> lines) {
|
||||
|
||||
final LanguageMap map = new LanguageMap();
|
||||
|
||||
for (String s : lines) {
|
||||
String[] pair = process(config, s);
|
||||
if (!isUnreadable(pair)) {
|
||||
map.put(pair[0], pair[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,20 @@ package cn.glycol.t18n;
|
|||
|
||||
public interface LanguageMapConfiguration {
|
||||
|
||||
/**
|
||||
* 获取分割符<br>
|
||||
* 用于将键和值分割开来
|
||||
* @param s 每行文字
|
||||
* @return 分隔符
|
||||
*/
|
||||
public String getSplitter(String s);
|
||||
|
||||
/**
|
||||
* 检测是否是注解<br>
|
||||
* 如果是注解,则忽略本行
|
||||
* @param s 每行文字
|
||||
* @return 是否是注解,<code>true</code>则忽略读取
|
||||
*/
|
||||
public boolean isAnnotation(String s);
|
||||
|
||||
public static final LanguageMapConfiguration DEFAULT = new LanguageMapConfiguration() {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package cn.glycol.t18n;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Objects;
|
||||
|
||||
public class T18n extends I18n {
|
||||
|
||||
/**
|
||||
* 设置本地化对照表
|
||||
* @param map 本地化对照表
|
||||
*/
|
||||
public static void set(LanguageMap map) {
|
||||
Objects.requireNonNull(map, "map cannot be null");
|
||||
I18n.map = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加额外的本地化对照表
|
||||
* @param map 本地化对照表
|
||||
*/
|
||||
public static void add(LanguageMap map) {
|
||||
Objects.requireNonNull(map, "map cannot be null");
|
||||
I18n.map.putAll(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输出的编码
|
||||
* @param charset 编码
|
||||
*/
|
||||
public static void charset(Charset charset) {
|
||||
Objects.requireNonNull(charset, "charset cannot be null");
|
||||
I18n.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地化对照表
|
||||
*/
|
||||
public static LanguageMap map() {
|
||||
return I18n.map;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package cn.glycol.t18n;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
public class T18nUtils {
|
||||
|
||||
/** 从在线网站上读取内容 */
|
||||
public static List<String> getOnlineContent(String _url) {
|
||||
|
||||
URL url;
|
||||
try {
|
||||
url = new URL(_url);
|
||||
} catch(MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
InputStream is = conn.getInputStream();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
List<String> lines = new ArrayList<String>();
|
||||
String s;
|
||||
while((s = br.readLine()) != null) {
|
||||
lines.add(s);
|
||||
}
|
||||
is.close();
|
||||
br.close();
|
||||
return lines;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 从本地文件读取内容 */
|
||||
public static List<String> getLocalContent(File file) {
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
return Files.readAllLines(file.toPath(), Charset.forName("UTF-8"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/** 保存翻译表到文件 */
|
||||
public static void saveLanguageMap(LanguageMap map, File file) {
|
||||
|
||||
Objects.requireNonNull(map);
|
||||
Objects.requireNonNull(file);
|
||||
|
||||
try {
|
||||
|
||||
String content = "";
|
||||
for(Entry<String, String> entries : map.entrySet()) {
|
||||
content += entries.getKey() + "=" + entries.getValue() + "\n";
|
||||
}
|
||||
|
||||
if(!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
FileWriter fw = new FileWriter(file);
|
||||
fw.write(content);
|
||||
fw.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Unable to write "+file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 使字符串列表扁平化。 */
|
||||
public static String flattenList(List<String> vlist) {
|
||||
|
||||
String v = "";
|
||||
for(String o : vlist) {
|
||||
v += o + "\n";
|
||||
}
|
||||
v = v.trim();
|
||||
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue