使用InputStreamReader两次

时间:2016-06-28 14:50:40

标签: java utf-8 character-encoding inputstream

我必须在阅读之前检查文件的编码。要检查编码,我使用此方法:

        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时,我的清单是空的。我想是因为我读了两次文件。我应该怎么做?

2 个答案:

答案 0 :(得分:1)

final InputStreamReader input = new InputStreamReader(is, decoder);

您的InputStreamReader将读取输入流中的所有数据。这意味着没有可用的数据。另外你已经把它关了。

您需要创建两次InputStream。一次测试字符集,再一次实际读取数据。

所以改变

InputStream is = new FileInputStream(file);
checkFileEncoding(is);

InputStream is = new FileInputStream(file);
checkFileEncoding(is);
is = new FileInputStream(file);

也是在

之后
try(CSVReader reader ..
..
}

添加

is.close();

答案 1 :(得分:0)

尝试Guess Encoding库。

Charset charset = CharsetToolkit.guessEncoding(file, 4096, StandardCharsets.UTF_8);

这应该会返回预期的结果。

我对HTML文件进行了尝试,结果是US-ASCII为charset。

您可以尝试Any23

Charset charset = Charset.forName(new TikaEncodingDetector().guessEncoding(new FileInputStream(file)));