嘿家伙我一直在使用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。
您的利益\:\线<} {\ rtlch \ FCS1 \ AF0 \ ltrch \ fcs0 \ insrsid5071958Ç} {\ rtlch \ FCS1 \ AF0 \ ltrch \ fcs0 \ insrsid10116111 IV} {\ rtlch \ FCS1 \ AF0 \ ltrch \ fcs0 \ insrsid5071958
C
} {\ rtlch \ fcs1 \ afch \ fcs0 \ insrsid10116111lient
>lastname
} {\ rtlch \ fcs1 \ afcs \ ltrch \ fcs0 \ insrsid10116111>firstname
} {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid10116111 > \线A
} {\ rtlch \ FCS1 \ AF0 \ ltrch \ fcs0 \ insrsid10116111dresse
} {\ rtlch \ FCS1 \ AF0 \ ltrch \ fcs0 \ insrsid5071958C
} {\ rtlch \ FCS1 \ AF0 \ ltrch \ fcs0 \ insrsid10116111绑定> \ lineCPClient
} {\ rtlch \ fcs1 \ af0 \ lcch \ fcs0 \ insrsid10116111>
显然,该文件包含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
格式。
它或者像源文件中的那样,或者当您写入同一文件时通过流输入来尝试“就地重写”导致此问题。通常,写入新文件,完成后,将新文件移到旧文件上(关闭所有流后)。或者,使用RandomAccessFile并就地覆盖,但请注意,要覆盖到位,您无法删除或添加字符(仅替换它们)。这是文件系统的限制,而不是java。
注意:您正在阅读强制性字符集:ISO_8859_1。但写作时你不要这样做。这意味着在平台默认字符集编码不是ISO_8859_1的任何系统上,此作业不仅会替换CivClient和“小于”符号,还会重新编码整个字符集,您可能也想修复它。