Java reader.readLine()不会在文件中返回确切的行

时间:2019-03-05 14:07:25

标签: java file bufferedreader readline

伙计们,我一直在使用BufferedReader,实际上直到发现一些单词之前我都没有注意到这个确切的问题,我试图替换文件中的某些单词,但遇到这种方法我没有得到我期望的确切结果是文件中的同一行,这是我的代码在下面

BufferedReader reader = new BufferedReader(
               new InputStreamReader(
                          new FileInputStream("C:\\files\\myfile.rtf"), StandardCharsets.ISO_8859_1));
    PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream("C:\\files\\my2file.rtf")));
    String str;

    while ((str = reader.readLine()) != null) {
        System.out.println(str);

    str = str.replace("CivClient", "myname"); // doesn't work
    str = str.replace("AdresseClient", "myname"); // doesn't work
    str = str.replace("lastname", "myname");
    str = str.replace("firstname", "myname");

    }
    writer.close();
    reader.close();

执行此代码,我发现“ CivClient”一词并没有出现,而是分开了 这是日志的一部分,而不是全部。您会注意到该词没有按原样出现。 感谢你的付出。亲爱的stackoverflowers。

  

VOS PRESTATIONS \〜:\ line <} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0   \ insrsid5071958 C} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid10116111   iv} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid5071958 C} {\ rtlch \ fcs1 \ af0   \ ltrch \ fcs0 \ insrsid10116111 lient> <} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0   \ insrsid13635392 \ charrsid13635392 lastname} {\ rtlch \ fcs1 \ af0   \ ltrch \ fcs0 \ insrsid10116111> <} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0   \ insrsid13635392 \ charrsid13635392 firstname} {\ rtlch \ fcs1 \ af0   \ ltrch \ fcs0 \ insrsid10116111> \ line <} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0   \ insrsid5071958 A} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid10116111   dresse} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid5071958   C} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid10116111 lient> \ line   <} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid13635392   CPClient} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid10116111>   <} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid13635392   VilleClient} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid10116111>

2 个答案:

答案 0 :(得分:3)

显然,该文件包含RTF,富文本格式而不是纯文本格式-正如已经建议的.rtf文件结尾。 \rtlch也可能表示从右到左的字符。您可以使用swing的StyledDocument RTFEditorKit来读取文件。

Path path = Paths.get("C:\\files\\myfile.rtf");
byte[] content = Files.readAllBytes(path);
String rtf = new String(content, StandardCharsets.ISO_8859_1);
StringReader in = new StringReader(rtf);
RTFEditorKit kit = new RTFEditorKit();
Document doc = kit.createDefaultDocument();
kit.read(in, doc, 0);
String text = doc.getText(0, doc.getLength());

该代码是一步一步的,您可以像您一样立即阅读。


将文本写回文件:

问题是RTF本质。如您所见,“ CivClient”在中间使用不同的RTF属性进行拆分,最简单的解决方案是手动创建正确 RTF。删除单词中的垃圾。

然后您的代码将起作用:

Path path = Paths.get("C:\\files\\myfile.rtf");
byte[] content = Files.readAllBytes(path);
String str = new String(content, StandardCharsets.ISO_8859_1);
str = str.replace("CivClient", "myname");
str = str.replace("AdresseClient", "myname");
str = str.replace("lastname", "myname");
str = str.replace("firstname", "myname");
content = str.getBytes(StandardCharsets.ISO_8859_1);
Files.write(path, content);

ISO-8859-1(拉丁文1)是受限制的字符集。在RTF中利用UTF-16支持:

str = str.chars()
    .map(ch -> ch < 128 ? Character.toString(ch) : String.format("\\u%04X", (int)ch))
    .collect(Collectors.joining(""));

将特殊字符转换为\uXXXX格式。

答案 1 :(得分:0)

这可能是源文件中的问题,或者是您在写入同一文件时通过流式传输输入来尝试进行“就地重写”的原因。通常,写入新文件,完成后,将新文件移到旧文件上(关闭所有流之后)。或者,使用RandomAccessFile并就地覆盖,但是请注意,要就地覆盖,您不能删除或添加字符(只能替换它们)。这是文件系统的限制,而不是Java。

注意:您正在阅读带有强制字符集:ISO_8859_1。但是在编写时不要这样做。这意味着,在平台默认字符集编码不是ISO_8859_1的任何系统上,此工作不仅会替换CivClient和'小于'符号,还会重新编码整个字符集,您可能也想解决这个问题。