我正在编写一个函数,该函数应该检测使用的字符集,然后将其切换为 utf-8。我正在使用juniversalchardet,它是mozilla 的universalchardet 的java 端口。
这是我的代码:
private List<List<String>> setProperEncoding(List<List<String>> input) {
try {
// Detect used charset
UniversalDetector detector = new UniversalDetector(null);
int position = 0;
while ((position < input.size()) & (!detector.isDone())) {
String row = null;
for (String cell : input.get(position)) {
row += cell;
}
byte[] bytes = row.getBytes();
detector.handleData(bytes, 0, bytes.length);
position++;
}
detector.dataEnd();
Charset charset = Charset.forName(detector.getDetectedCharset());
Charset utf8 = Charset.forName("UTF-8");
System.out.println("Detected charset: " + charset);
// rewrite input using proper charset
List<List<String>> newLines = new ArrayList<List<String>>();
for (List<String> row : input) {
List<String> newRow = new ArrayList<String>();
for (String cell : row) {
//newRow.add(new String(cell.getBytes(charset)));
ByteBuffer bb = ByteBuffer.wrap(cell.getBytes(charset));
CharBuffer cb = charset.decode(bb);
bb = utf8.encode(cb);
newRow.add(new String(bb.array()));
}
newLines.add(newRow);
}
return newLines;
} catch (Exception e) {
e.printStackTrace();
return input;
}
}
我的问题是,当我读取包含波兰字母表等字符的文件时,诸如 ł、ą、ć 和类似字符之类的字母会被替换为 ?和其他奇怪的事情。我做错了什么?
编辑: 为了进行编译,我使用 eclipse。
方法参数是读取MultipartFile的结果。只需使用 FileInputStream 获取每一行,然后用某个分隔符分割每一行(它是为 xls、xlsx 和 csv 文件准备的)。没什么特别的。
最佳答案
首先,您的数据采用二进制格式。为了简单起见,我认为它来自 InputStream
。
您想将输出写入 UTF-8
字符串,我想它可以是一个 OutputStream。
我建议创建一个AutoDetectInputStream
:
public class AutoDetectInputStream extends InputStream {
private InputStream is;
private byte[] sampleData = new byte[4096];
private int sampleLen;
private int sampleIndex = 0;
public AutoDetectStream(InputStream is) throws IOException {
this.is = is;
// pre-read the data
sampleLen = is.read(sampleData);
}
public Charset getCharset() {
// detect the charset
UniversalDetector detector = new UniversalDetector(null);
detector.handleData(sampleData, 0, sampleLen);
detector.dataEnd();
return detector.getDetectedCharset();
}
@Override
public int read() throws IOException {
// simulate the stream for the reader
if(sampleIndex < sampleLen) {
return sampleData[sampleIndex++];
}
return is.read();
}
}
第二个任务非常简单,因为Java将字符串(字符)存储在UTF-8
中,因此只需使用一个简单的OutputStreamWriter即可。所以,这是您的代码:
// open input with Detector stream
// we use BufferedReader so we could read lines
InputStream is = new FileInputStream("in.txt");
AutoDetectInputStream detector = new AutoDetectInputStream(is);
Charset charset = detector.getCharset();
// here we can use the charset to decode the bytes into characters
BufferedReader rdr = new BufferedReader(new InputStreamReader(detector, charset));
// open output to write to
OutputStream os = new FileOutputStream("out.txt");
Writer utf8Writer = new OutputStreamWriter(os, Charset.forName("UTF-8"));
// copy the whole file
String line;
while((line = rdr.readLine()) != null) {
utf8Writer.append(line);
}
// close streams
rdr.close();
utf8Writer.flush();
utf8Writer.close();
所以,最终您将所有 txt 文件转码为 UTF-8。
请注意,缓冲区大小应足以满足 UniversalDetector
的需求。
关于java - 更改java中的编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17677776/