Java读取UCS-2 LE带BOM日志文件,如何正确读取支持字符串操作?
正确读取UCS-2 LE带BOM日志文件的解决方案
你遇到的问题核心是编码不匹配导致的乱码:UCS-2 LE本质就是UTF-16LE(双字节编码),而你用单字节的CP1252读取时,会把每个双字节字符拆成两个单字节乱码——比如ASCII字符"I"在UTF-16LE里是0x49 0x00,用CP1252读出来就变成"I"加一个空字符,这样你的contains("INFO")自然匹配不到目标子串。
这里有两种简单可靠的解决方法:
方法一:自动识别UTF-16编码(推荐)
Java的StandardCharsets.UTF_16会自动检测UTF-16的BOM(字节顺序标记),不管是LE还是BE编码都能正确处理,直接替换你的字符集参数就行:
import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; public class LogProcessor { public static void main(String[] args) throws Exception { // 用UTF-16字符集读取,自动处理BOM和字节顺序 List<String> lines = Files.readAllLines(Paths.get("sample.log"), StandardCharsets.UTF_16); for (String s : lines) { if (s.contains("INFO")) { System.out.println(s); } } } }
这个方法最省心,不需要手动处理BOM,Java会帮你搞定所有细节。
方法二:指定UTF-16LE并手动跳过BOM(适合明确编码场景)
如果你确定文件是UTF-16LE带BOM,也可以手动跳过开头的2字节BOM(0xFF 0xFE),再用UTF-16LE读取:
import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.io.BufferedReader; import java.io.InputStreamReader; public class LogProcessor { public static void main(String[] args) throws Exception { try (BufferedReader reader = new BufferedReader( new InputStreamReader(Files.newInputStream(Paths.get("sample.log")), StandardCharsets.UTF_16LE))) { // 跳过BOM(UTF-16LE的BOM是\uFEFF,若存在则读取跳过,不存在则重置指针) reader.mark(1); if (reader.read() != '\uFEFF') { reader.reset(); } String line; while ((line = reader.readLine()) != null) { if (line.contains("INFO")) { System.out.println(line); } } } } }
不过这种方法不如第一种灵活,除非你有特殊需求,否则优先用方法一。
替换字符集后,读取的字符串会是正常的Unicode字符,后续的contains、equals等字符串操作都能正常工作啦。
内容的提问来源于stack exchange,提问作者Twonky
相关产品推荐
相关产品推荐

