【问题标题】:Java reader.readLine() dosn't return the exact line in the fileJava reader.readLine() 不返回文件中的确切行
【发布时间】:2019-03-05 14:07:24
【问题描述】:

嘿,伙计们,我一直在使用 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 C}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10116111 lient> lastname}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10116111 > firstname}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10116111 >\line A}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10116111 dresse}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5071958 C}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10116111 lient>\line CPClient}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10116111 >

【问题讨论】:

  • 请正确格式化您的示例。另外,请尽量不要写入您正在读取的同一文件,尤其是在使用不同编码时。这可能会影响结果。而是写入临时文件,成功后删除旧文件并复制/移动临时文件以替换它(或者将临时文件的内容复制到原始文件中)。
  • 作为一种方法来确定您的问题是在阅读器中还是在您的替换语句中,当您注释掉 str.replace 行时,文件是否会像原始文件一样打印出来?
  • 您能否清楚说明您读取的数据的结构、您获得的确切输出以及您的预期?
  • 一次读写同一个文件是个坏主意,除非你想深入了解文件系统细节,否则不要这样做。
  • 是的,文档与其他占位符一起打印得很清楚,这里的问题是 readline() 上的某些单词不会像其他单词一样出现,有些被替换,而其他单词则没有,@BreakBB 它是我正在阅读的只是一个 rtf 文件,占位符是 但问题是所有其他单词都只被替换了这个。我没有同时读取和写入我更改了文件名。

标签: java file bufferedreader readline


【解决方案1】:

显然,该文件包含 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,Latin-1,是一个有限的字符集。利用 RTF 中的 UTF-16 支持:

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

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

【讨论】:

  • 谢谢先生您的响应回答,但您能澄清一下我如何通过这种方法编辑现有文件吗?我仍然是这方面的初学者。
  • 字符串text 将包含文件的内容。如果您想编辑/更改文件,这意味着更改文档并将其写回。我会尝试添加代码。
【解决方案2】:

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

注意:您正在阅读强制字符集:ISO_8859_1。但是在写作时你不要这样做。这意味着在平台默认字符集编码不是 ISO_8859_1 的任何系统上,此作业不仅会替换 CivClient 和“小于”符号,还会重新编码整个字符集,您可能也想修复它。

【讨论】:

  • 实际上我正在使用 2 个不同的文件 1 用于写入和一个用于读取,关于强制字符集,我只是想尝试 readline() 函数可能会更改输出。我试过没有,也没有其他人的字符集,但我什么也没得到。它总是同样的问题
猜你喜欢
  • 2016-07-09
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-05
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
相关资源
最近更新 更多