英文:
Failing to write multiple lines in a text files java loop
问题
以下是翻译好的内容:
我正在尝试将从文件中读取的许多行写入第二个文件。我能够循环遍历文本行(sout 可以打印出所有行),但不能将所有行写入新文件。它只写入最后一行。
任何帮助:
lines.forEach(line -> {
// 添加行分隔符
String lineToWrite = line; // + System.lineSeparator(); //
// 将每一行写入输出文件
try {
//Files.write(output, lineToWrite.getBytes(StandardCharsets.UTF_8));
//Files.write(output, Collections.singleton(lineToWrite),StandardCharsets.UTF_8);
PrintWriter writer = new PrintWriter(outputdir, "UTF-8");
writer.println(lineToWrite);
System.out.println(lineToWrite);
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("错误行 linewrite:" + e);
}
});
英文:
I am trying to write many lines read from a file to a second file. I am able to loop through lines (sout can print all lines) of text but it's not possible to write all lines in the new file. It writes only the last line.
Any help:
lines.forEach(line -> {
// Append the line separator
String lineToWrite = line; // + System.lineSeparator(); //
// Write every line to the output file
try {
//Files.write(output, lineToWrite.getBytes(StandardCharsets.UTF_8));
//Files.write(output, Collections.singleton(lineToWrite),StandardCharsets.UTF_8);
PrintWriter writer = new PrintWriter(outputdir, "UTF-8");
writer.println(lineToWrite);
System.out.println(lineToWrite);
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("error lines linewrite:"+e);
}
});
答案1
得分: 1
你每读取一行就打开文件进行读取,然后写入一行,然后关闭文件?这样做效率极低。
此外,写入操作会引发(已检查的)异常,而异常和 lambda 表达式不太搭配。
在这里使用 .forEach
是愚蠢的;关于 lambda 表达式的问题在于它们不透明地处理异常,不透明地处理可变局部变量,并且不透明地处理控制流。这些都是不好的。使用 lambda 表达式必须有足够的优势来抵消这些缺点,或者 lambda 表达式必须在上下文中分开(在这种情况下,这三个不足就会变成优点)。但在这里,两者都不是情况,所以不要使用这只旧鞋来钉这颗钉子,要使用锤子。因此:
public static void main(String[] args) throws Exception {
List<String> lines = ...;
String file = "example.txt";
try (PrintWriter out = new PrintWriter(file, "UTF-8")) {
for (String line : lines) {
out.println(line);
System.out.println(line);
}
}
}
上述代码还修复了你的代码中的其他错误,比如没有正确关闭资源,以及糟糕的异常管理方式,通过让系统处理程序打印错误,这通常会更好。如果不知道如何处理,"我不知道如何处理这个" 的最佳处理程序不是你写的那种,而是这样的:
catch (IOException iCantHandleThis) {
throw new RuntimeException("Uncaught", iCantHandleThis);
}
- 但最好还是像上面的示例那样将异常原样抛出。
英文:
You're opening the file for reading, writing one line, and then closing it, for every line? That is incredibly inefficient.
Also, writing causes (checked) exceptions, and exceptions + lambdas don't work well.
.forEach
here is silly; the problem with lambdas are that they are not exception transparent, not mutable local variable transparent, and not control flow transparent. These are bad things. The use of the lambda needs to have enough positives to outweigh these negatives, OR the lambda needs to be separated in context (at which point those 3 downsides turn into upsides). Neither is the case here, so don't use this old shoe to fasten than nail, use a hammer. Thus:
public static void main(String[] args) throws Exception {
List<String> lines = ...;
String file = "example.txt";
try (PrintWriter out = new PrintWriter(file, "UTF-8")) {
for (String line : lines) {
out.println(line);
System.out.println(line);
}
}
}
The above also fixes other errors in your code, such as not properly closing the resource, and deplorable exception management, by letting the system handler print the error, which does a better job generally. If somehow you can't, the 'best' "I don't know what to do with this" handler is not what you wrote, but this:
catch (IOException iCantHandleThis) {
throw new RuntimeException("Uncaught", iCantHandleThis);
}
- but prefer throwing the exception onwards as is done in the example above.
答案2
得分: 0
我将文件提取出循环,显然这是我的错误。
String outputdir = "C:\\merged\\Merged.txt";
Path output = Paths.get(outputdir);
Path directory = Paths.get("C:\\scan");
Stream<Path> filesToProcess = Files.list(directory);
// 首先删除先前合并的文件并创建一个新的 //
File file = new File("C:\\merged\\Merged.txt");
try {
boolean result = Files.deleteIfExists(file.toPath());
} catch (IOException e) {
System.out.println("删除先前文件时出错:" + e);
e.printStackTrace();
}
PrintWriter writer = new PrintWriter(outputdir, "UTF-8");
// 遍历所有文件
filesToProcess.forEach(path -> {
// 获取文件的所有行
Stream<String> lines = null;
try {
lines = Files.lines(path);
} catch (IOException e) {
System.out.println("读取文件行时出错:" + e);
e.printStackTrace();
}
// 遍历所有行
lines.forEach(line -> {
// 添加行分隔符
String lineToWrite = line; // + System.lineSeparator(); 如果需要的话 //
// 将每行写入输出文件
// Files.write(output, lineToWrite.getBytes(StandardCharsets.UTF_8));
// Files.write(output, Collections.singleton(lineToWrite),StandardCharsets.UTF_8);
writer.println(lineToWrite);
System.out.println(lineToWrite);
});
});
writer.close();
英文:
I pulled File out of the loop and obviously this was my mistake.
String outputdir = "C:\\merged\\Merged.txt";
Path output = Paths.get(outputdir);
Path directory = Paths.get("C:\\scan");
Stream<Path> filesToProcess = Files.list(directory);
// first delete previous merged and create a new on//
File file = new File("C:\\merged\\Merged.txt");
try {
boolean result = Files.deleteIfExists(file.toPath());
} catch (IOException e) {
System.out.println("error deleteprev file:"+e);
e.printStackTrace();
}
PrintWriter writer = new PrintWriter(outputdir, "UTF-8");
// Iterate all files
filesToProcess.forEach(path -> {
// Get all lines of that file
Stream<String> lines = null;
try {
lines = Files.lines(path);
} catch (IOException e) {
System.out.println("error lines path:"+e);
e.printStackTrace();
}
// Iterate all lines
lines.forEach(line -> {
// Append the line separator
String lineToWrite = line; // + System.lineSeparator(); Nese duhet //
// Write every line to the output file
//Files.write(output, lineToWrite.getBytes(StandardCharsets.UTF_8));
//Files.write(output, Collections.singleton(lineToWrite),StandardCharsets.UTF_8);
writer.println(lineToWrite);
System.out.println(lineToWrite);
});
});
writer.close();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论