Java BufferedReader - 空行问题
Java BufferedReader - empty line issue
问题描述: 例如我们有一个文本文件file.txt,内容如下:
Hello(LS)
what(LS)
are(LS)
<empty_line>(LS)
you(LS)
doing(LS)
<empty_line>(LS)
<empty_line>(LS)
now(LS)
<empty_line>(LS)
<empty_line>(LS)
<empty_line>(EOF)
(LS - 行分隔符,EOF - 文件结尾)
如果我理解文本文件的概念,那么该文件看起来就像那样。现在,我想用这个文本填充例如 TextArea(来自 JavaFX)。我可以使用以下用 try-catch 包围的代码(close() 方法将在 finnaly 块中):
TextArea textArea = new TextArea();
BufferedReader br = new BufferedReader(new FileReader(new File("file.txt")));
String line;
while ((line = br.readLine()) != null) {
textArea.appendText(line);
textArea.appendText("\n");
}
该代码有一个大问题 - 每当文本文件不以 empty_line 结尾时,目标 TextArea 中就会多一行。当 empty_line 包含在 EOF 之前的文件时,加载到 TextArea 是正确的。我尝试了很多方法,但每次都出现问题。
为什么选择 BufferedReader?
我选择 BufferedReader 是因为我只想要一些可以逐行读取源文本文件的 reader。我想要 reader,因为文件分隔符和 OS 独立性。
我对它有什么期望?
我正在等待我逐行读取文件,当我阅读时,我设置了自定义分隔符(独立于源文件行分隔符) - 例如 LF(“\n”)。我正在等待可能有不同行分隔符的完全相同的内容!当我写入某个文件时(我也在使用 BufferedReader
的地方(实习生从 TextArea 读取文本并根据用户 OS (System.getProperty("line.separator")
) 设置行分隔符)有一个类似的行为。
我尝试了什么?
我尝试了很多方法如何做到这一点。我还尝试在 class BufferedReader 中使用方法 read() 并将它的 return 值与 -1 进行比较,这意味着 EOF。但是,有一个问题,我想使用自定义文件分隔符,但我没有时间编写一些解析器。
我的问题:如何使用自定义行分隔符将文件内容写入 TextArea(或任何字符串),而无需任何额外或更少的行?
*如您所见,我的英语不是很好,所以希望您能理解我,谢谢。
您正在自己添加换行符。
while ((line = br.readLine()) != null) {
textArea.appendText(line);
textArea.appendText("\n");
}
while循环中的第二行添加下一行。每次执行该语句时,光标将转到下一行。
因此,当文件游标从文件中读取最后一行时,它会将其附加到 textArea,然后再附加一个换行符。这就是为什么你在最后得到额外的空白行。
if((line = br.readLine()) != null)
textArea.appendText(line);
while ((line = br.readLine()) != null) {
textArea.appendText("\n");
textArea.appendText(line);
}
正如讨论中所证明的那样,问题在于 readLine()
以下文件的行为方式相同:
File A: "Hello\n"
File B: "Hello"
1st readLine() --> "Hello"
2nd readLine() --> null
==> we cannot know if there was a '\n' after the last line or not
解决方法:使用其他方法读取字符,这里解释其中两种:
一次一个字符:
String readFile(String file) throws IOException {
FileReader fr = new FileReader(new File(file));
String s = "";
int c;
while ((c = fr.read()) >= 0) {
s += (c == '\n' ? myCharOrString : (char)c;
}
return s;
}
缓冲:
String readFile(String file, int bufferSize) throws IOException {
FileReader fr = new FileReader(new File(file));
char[] buffer = new char[bufferSize];
int charsRead;
String s = "";
while ((charsRead = fr.read(buffer)) > 0) {
s += new String(buffer, 0, charsRead);
}
return s.replaceAll("\r\n?", "\n");
}
好的,
我做到了!我不知道这种效果有多大,或者我是否可以使用与 BufferedReader 不同的 Reader,但这对我有用:
TextArea textArea = new TextArea();
String someString;
bufferedReader = new BufferedReader(new FileReader(file));
StringBuilder codeTextArea = new StringBuilder();
int character;
while ((character = bufferedReader.read()) != -1)
codeTextArea.append((char) character);
//for TextArea you can use just toString and it set up separators to LF
this.textArea.setText(codeTextArea.toString());
//for String where you want line separator LF you can use for example following regex expression
someString = codeTextArea.toString().replaceAll("\r\n?","\n");
正如您在第二种情况中看到的那样,我使用正则表达式来检测和替换行分隔符。该代码可以读取带有分隔符 LF、CR、CRLF 的文本文件,并在内存要求最低的 TextArea 或 String 中正确填充(包括 最后一个空行),因为一个字符 (" \n") 用于分隔行,也对应于 TextArea 默认行分隔符(它使用相同的 - LF)。
该代码可能不是很简单,但它可以工作。所以我问你是否知道如何简化它以获得最佳硬件性能。
问题描述: 例如我们有一个文本文件file.txt,内容如下:
Hello(LS)
what(LS)
are(LS)
<empty_line>(LS)
you(LS)
doing(LS)
<empty_line>(LS)
<empty_line>(LS)
now(LS)
<empty_line>(LS)
<empty_line>(LS)
<empty_line>(EOF)
(LS - 行分隔符,EOF - 文件结尾)
如果我理解文本文件的概念,那么该文件看起来就像那样。现在,我想用这个文本填充例如 TextArea(来自 JavaFX)。我可以使用以下用 try-catch 包围的代码(close() 方法将在 finnaly 块中):
TextArea textArea = new TextArea();
BufferedReader br = new BufferedReader(new FileReader(new File("file.txt")));
String line;
while ((line = br.readLine()) != null) {
textArea.appendText(line);
textArea.appendText("\n");
}
该代码有一个大问题 - 每当文本文件不以 empty_line 结尾时,目标 TextArea 中就会多一行。当 empty_line 包含在 EOF 之前的文件时,加载到 TextArea 是正确的。我尝试了很多方法,但每次都出现问题。
为什么选择 BufferedReader? 我选择 BufferedReader 是因为我只想要一些可以逐行读取源文本文件的 reader。我想要 reader,因为文件分隔符和 OS 独立性。
我对它有什么期望?
我正在等待我逐行读取文件,当我阅读时,我设置了自定义分隔符(独立于源文件行分隔符) - 例如 LF(“\n”)。我正在等待可能有不同行分隔符的完全相同的内容!当我写入某个文件时(我也在使用 BufferedReader
的地方(实习生从 TextArea 读取文本并根据用户 OS (System.getProperty("line.separator")
) 设置行分隔符)有一个类似的行为。
我尝试了什么? 我尝试了很多方法如何做到这一点。我还尝试在 class BufferedReader 中使用方法 read() 并将它的 return 值与 -1 进行比较,这意味着 EOF。但是,有一个问题,我想使用自定义文件分隔符,但我没有时间编写一些解析器。
我的问题:如何使用自定义行分隔符将文件内容写入 TextArea(或任何字符串),而无需任何额外或更少的行?
*如您所见,我的英语不是很好,所以希望您能理解我,谢谢。
您正在自己添加换行符。
while ((line = br.readLine()) != null) {
textArea.appendText(line);
textArea.appendText("\n");
}
while循环中的第二行添加下一行。每次执行该语句时,光标将转到下一行。 因此,当文件游标从文件中读取最后一行时,它会将其附加到 textArea,然后再附加一个换行符。这就是为什么你在最后得到额外的空白行。
if((line = br.readLine()) != null)
textArea.appendText(line);
while ((line = br.readLine()) != null) {
textArea.appendText("\n");
textArea.appendText(line);
}
正如讨论中所证明的那样,问题在于 readLine()
以下文件的行为方式相同:
File A: "Hello\n"
File B: "Hello"
1st readLine() --> "Hello"
2nd readLine() --> null
==> we cannot know if there was a '\n' after the last line or not
解决方法:使用其他方法读取字符,这里解释其中两种:
一次一个字符:
String readFile(String file) throws IOException {
FileReader fr = new FileReader(new File(file));
String s = "";
int c;
while ((c = fr.read()) >= 0) {
s += (c == '\n' ? myCharOrString : (char)c;
}
return s;
}
缓冲:
String readFile(String file, int bufferSize) throws IOException {
FileReader fr = new FileReader(new File(file));
char[] buffer = new char[bufferSize];
int charsRead;
String s = "";
while ((charsRead = fr.read(buffer)) > 0) {
s += new String(buffer, 0, charsRead);
}
return s.replaceAll("\r\n?", "\n");
}
好的, 我做到了!我不知道这种效果有多大,或者我是否可以使用与 BufferedReader 不同的 Reader,但这对我有用:
TextArea textArea = new TextArea();
String someString;
bufferedReader = new BufferedReader(new FileReader(file));
StringBuilder codeTextArea = new StringBuilder();
int character;
while ((character = bufferedReader.read()) != -1)
codeTextArea.append((char) character);
//for TextArea you can use just toString and it set up separators to LF
this.textArea.setText(codeTextArea.toString());
//for String where you want line separator LF you can use for example following regex expression
someString = codeTextArea.toString().replaceAll("\r\n?","\n");
正如您在第二种情况中看到的那样,我使用正则表达式来检测和替换行分隔符。该代码可以读取带有分隔符 LF、CR、CRLF 的文本文件,并在内存要求最低的 TextArea 或 String 中正确填充(包括 最后一个空行),因为一个字符 (" \n") 用于分隔行,也对应于 TextArea 默认行分隔符(它使用相同的 - LF)。
该代码可能不是很简单,但它可以工作。所以我问你是否知道如何简化它以获得最佳硬件性能。