使用此代码运行文件在第一次运行时效果很好,
但是在第二次运行时(在同一个文件上),Files.readAllLines
抛出异常。
所有代码都是(对于每个文件,但在这种情况下,它只是一个) 获取文件中的所有行,将其删除,然后使用相同的内容重新填充。
for (File file : content) {
List<String> fillLines = new ArrayList<>();
try {
fillLines = Files.readAllLines(file.toPath());
} catch (IOException e) {
e.printStackTrace();
}
if (fillLines.size() > 0) {
file.delete();
FileWriter fileWriter = new FileWriter(file, false);
for (String line : fillLines) {
fileWriter.write(line);
if (fillLines.indexOf(line) < fillLines.size() - 1)
fileWriter.append(System.lineSeparator());
}
fileWriter.close();
}
}
有什么想法吗?可能是因为fileWriter.append(System.lineSeparator());
?
所有其他提问者第一次失败是因为用错误的字符集阅读。但是,由于我能够运行一次,我不是在阅读而是写错了,所以更改字符集似乎是一种可以避免的解决方法。
堆栈跟踪:
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.nio.file.Files.readAllLines(Unknown Source)
at java.nio.file.Files.readAllLines(Unknown Source)
这里的任何内容都指向
fillLines = Files.readAllLines(file.toPath());
答案 0 :(得分:4)
来自Files.readAllLines()的文档:
使用UTF-8字符集
将文件中的字节解码为字符
来自FileWriter的文档:
此类的构造函数假定默认字符编码和默认字节缓冲区大小是可接受的。要自己指定这些值,请在FileOutputStream上构造一个OutputStreamWriter。
因此,您使用的是默认平台编码(在您的情况下,不是UTF8),并使用UTF8进行读取。这是例外的原因。使用相同的编码进行写入和读取。上述文档说明了如何指定要写入的UTF8编码。
答案 1 :(得分:0)
for (File file : content) {
Path path = fiel.toPath();
List<String> fillLines;
try {
fillLines = Files.readAllLines(path);
} catch (IOException e) {
System.err.println("Error while reading " + path);
e.printStackTrace();
fillLines = new ArrayList<>();
}
if (!fillLines.isEmpty()) {
//Files.delete(path);
// See -A-
Files.write(path, fillLines, StandardOpenOptions.TRUNCATE_EXISTING);
}
}
为什么这样 - 即使它更短,更安全,更一致?
错误
您没有指明Charset的阅读和写作。
在Files
之前,这意味着使用了平台编码,并且存在一个重载的构造函数 一个字符集/字符串编码。
对于非常旧的FileReader/FileWriter
,即使不存在重载:它们也始终使用平台编码 - System.getProperty("file.encoding")
。
使用Files
Unicode的 UTF-8 成为默认值:由于java String包含Unicode,转换变为无损。 大!的
但是在使用像Windows-1252这样的东西后,使用UTF-8读取可能会失败,因为UTF-8要求第8位专门用于实现有效的多字节序列。
注意:原来该文件是UTF-8,但一旦编写,就不再是(没有有效的UTF-8)。
// -A-
// Possibly add a BOM (begin of file marker) to identify to Windows
// that this file is in UTF-8 (works for UTF-16 too).
// This is primarily for Notepad. A BOM is redundant, invisible (zero width space)
// and generally inadvisable if not needed.
if (!lines.get(0).startsWith("\uFEFF")) {
lines.set(0, "\uFEFF" + lines.get(0));
}