使用 InputStreamReader 两次
Use InputStreamReader twice
我必须在读取文件之前检查文件的编码。要检查编码,我使用此方法:
try {
CharsetDecoder decoder= Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
final InputStreamReader input = new InputStreamReader(is, decoder);
int data = input.read();
while(data != -1){
data = input.read();
}
input.close();
} catch (MalformedInputException e) {
LOGGER.error(The file encoding is wrong!");
throw new MalformedInputException(Math.toIntExact(file.length()));
}
}
这里是调用它的代码:
InputStream is = new FileInputStream(file);
checkFileEncoding(is);
List<MyObject> list = newArrayList();
try(CSVReader reader = new CSVReader(new InputStreamReader(is), ';')) {
list = reader.readAll().stream()
.skip(1) //
.map(myObjectMap)
.filter(o -> o != null)
.collect(toList());
}
问题是,当我之前调用 checkFileEncoding
时,我的列表是空的。我认为这是因为我读了我的文件两次。我应该怎么做?
final InputStreamReader input = new InputStreamReader(is, decoder);
您的 InputStreamReader 将从输入流中读取所有数据。这意味着不再有可用数据。另外你已经关闭了。
您需要创建 InputStream 两次。 1次测试字符集,1次实际读取数据。
所以改变
InputStream is = new FileInputStream(file);
checkFileEncoding(is);
到
InputStream is = new FileInputStream(file);
checkFileEncoding(is);
is = new FileInputStream(file);
也在
之后
try(CSVReader reader ..
..
}
添加
is.close();
尝试 Guess Encoding 库。
Charset charset = CharsetToolkit.guessEncoding(file, 4096, StandardCharsets.UTF_8);
这应该 return 您的预期结果。
我针对 HTML
文件进行了尝试,结果是 US-ASCII
作为字符集。
你可以试试Any23图书馆
Charset charset = Charset.forName(new TikaEncodingDetector().guessEncoding(new FileInputStream(file)));
我必须在读取文件之前检查文件的编码。要检查编码,我使用此方法:
try {
CharsetDecoder decoder= Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
final InputStreamReader input = new InputStreamReader(is, decoder);
int data = input.read();
while(data != -1){
data = input.read();
}
input.close();
} catch (MalformedInputException e) {
LOGGER.error(The file encoding is wrong!");
throw new MalformedInputException(Math.toIntExact(file.length()));
}
}
这里是调用它的代码:
InputStream is = new FileInputStream(file);
checkFileEncoding(is);
List<MyObject> list = newArrayList();
try(CSVReader reader = new CSVReader(new InputStreamReader(is), ';')) {
list = reader.readAll().stream()
.skip(1) //
.map(myObjectMap)
.filter(o -> o != null)
.collect(toList());
}
问题是,当我之前调用 checkFileEncoding
时,我的列表是空的。我认为这是因为我读了我的文件两次。我应该怎么做?
final InputStreamReader input = new InputStreamReader(is, decoder);
您的 InputStreamReader 将从输入流中读取所有数据。这意味着不再有可用数据。另外你已经关闭了。
您需要创建 InputStream 两次。 1次测试字符集,1次实际读取数据。
所以改变
InputStream is = new FileInputStream(file);
checkFileEncoding(is);
到
InputStream is = new FileInputStream(file);
checkFileEncoding(is);
is = new FileInputStream(file);
也在
之后try(CSVReader reader ..
..
}
添加
is.close();
尝试 Guess Encoding 库。
Charset charset = CharsetToolkit.guessEncoding(file, 4096, StandardCharsets.UTF_8);
这应该 return 您的预期结果。
我针对 HTML
文件进行了尝试,结果是 US-ASCII
作为字符集。
你可以试试Any23图书馆
Charset charset = Charset.forName(new TikaEncodingDetector().guessEncoding(new FileInputStream(file)));