从文件中读取字符时会丢失?

时间:2017-06-20 16:14:45

标签: java unicode

民间,

我有一些非ASCII输入,我需要使用分隔符进行解析。如果我在TextPad二进制模式下打开输入文件,我可以看到分隔符实际上是一个3字符的十六进制值C3,73和3F序列。那中间人物(“没有休息”控制角色)给了我悲伤。当我将文件读入java中的字符串时,该字符似乎被删除了。

示例代码(文件中只有一行:)

String escapedDelimiter = args[0];
String delimiter = StringEscapeUtils.unescapeJava(escapedDelimiter);
String s = null;

try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(args[1]), Charset.forName(args[2])))) {
    s = br.readLine();
}

System.out.println(delimiter);
System.out.println("delimiter length: " + delimiter.length());
System.out.println(s);
System.out.println("s length: " + s.length());

int i = s.indexOf(delimiter);
System.out.println(i);

输出:

  

一个?

     

分隔符长度:3

     

一个?HelloÃ?WorldÃ?

     

长度:16

     

-1

分隔符长度正确但长度不正确。该文件包含19个字节。缺少3个分隔符中的每个分区中的一个字符。

像这样对字符串进行硬编码是有效的,但我需要从文件中读取输入:

String s = "\u00C3\u0083\u003FHelloÃ\u0083?World";

有趣的是,在输入前3个转义字符后,在“Hello”之后复制并粘贴它们会导致它们被替换为\ \ u0083?。正是这个中间角色造成了麻烦。

有人知道发生了什么事吗?

感谢

2 个答案:

答案 0 :(得分:0)

我会将文件读作字节数组,寻找您想要的确切分隔符。然后将byte []转换为String。

如果性能/内存使用不是问题,我会使用Commons IO来读取字节。

https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/FileUtils.html#readFileToByteArray(java.io.File)

然后在数组中搜索所需的模式。最后,将其他块转换为String。

String value = new String(myBytes) ;

如果您担心性能/内存,请使用以下方式线性读取字节:

(byte) InputStream.read()

继续搜索分隔符。

答案 1 :(得分:0)

在代码new InputStreamReader(new FileInputStream(args[1]), Charset.forName(args[2]))中使用硬编码Charset.forName(args[2])替换StandardCharsets.UTF_8,看看是否有帮助。将其作为字节读取并作为字节工作可能会有所帮助。还有另一种工具可以帮助你 - 我编写了一个实用程序,可以将任何字符串转换为Unicode序列,反之亦然。玩这样的奇怪案例并将其转回并强行有时可以帮助您理解问题。以下是一篇文章的链接,该文章介绍了如何获取开源库以及如何使用它:Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparison。查找段落“ String Unicode converter