Java 如何仅使用FileReader读取多行?
我有以下代码:Java 如何仅使用FileReader读取多行?,java,filereader,Java,Filereader,我有以下代码: public class Reader { public static void main(String[] args) throws IOException { try (FileReader in = new FileReader("D:/test.txt")) { // BufferedReader br = new BufferedReader(in); int line = in .read();
public class Reader {
public static void main(String[] args) throws IOException {
try (FileReader in = new FileReader("D:/test.txt")) {
// BufferedReader br = new BufferedReader(in);
int line = in .read();
for (int i = 0; i < line; i++) {
//System.out.println(line);
System.out.println((char) line);
line = in .read();
}
}
}
}
当我运行上述代码时,它只读取
Hello
。我只想使用FileReader
阅读多行内容。我不想使用BufferedReader
或InputStreamReader
等。这可能吗?您必须逐字符读取内容并解析新行序列
新行序列可以是以下任意一种:
public List<String> readLinesUsingFileReader(String filename) throws IOException {
List<String> lines = null;
try (FileReader fileReader = new FileReader(filename)) {
lines = readLines(fileReader);
}
return lines;
}
private List<String> readLines(FileReader fileReader) throws IOException {
List<String> lines = new ArrayList<>();
boolean newLine = false;
int c, p = 0;
StringBuilder line = new StringBuilder();
while(-1 != (c = fileReader.read())) {
if(c == '\n' && p != '\r') {
newLine = true;
} else if(c == '\r') {
newLine = true;
} else {
if(c != '\n' && c != '\r') {
line.append((char) c);
}
}
if(newLine) {
lines.add(line.toString());
line = new StringBuilder();
newLine = false;
}
p = c;
}
if(line.length() > 0) {
lines.add(line.toString());
}
return lines;
}
'\r'
'\n'
“\r\n”
public List<String> readLinesUsingFileReader(String filename) throws IOException {
List<String> lines = null;
try (FileReader fileReader = new FileReader(filename)) {
lines = readLines(fileReader);
}
return lines;
}
private List<String> readLines(FileReader fileReader) throws IOException {
List<String> lines = new ArrayList<>();
boolean newLine = false;
int c, p = 0;
StringBuilder line = new StringBuilder();
while(-1 != (c = fileReader.read())) {
if(c == '\n' && p != '\r') {
newLine = true;
} else if(c == '\r') {
newLine = true;
} else {
if(c != '\n' && c != '\r') {
line.append((char) c);
}
}
if(newLine) {
lines.add(line.toString());
line = new StringBuilder();
newLine = false;
}
p = c;
}
if(line.length() > 0) {
lines.add(line.toString());
}
return lines;
}
使用创建的文件进行测试
@Test
public void readLinesUsingFileReader0() throws IOException {
List<String> lines = readLinesUsingFileReader(txt0);
Assert.assertEquals(3, lines.size());
Assert.assertEquals("Hello", lines.get(0));
Assert.assertEquals(",", lines.get(1));
Assert.assertEquals("World!", lines.get(2));
}
@Test
public void readLinesUsingFileReader1() throws IOException {
List<String> lines = readLinesUsingFileReader(txt1);
Assert.assertEquals(4, lines.size());
Assert.assertEquals("", lines.get(0));
Assert.assertEquals("", lines.get(1));
Assert.assertEquals("", lines.get(2));
Assert.assertEquals("", lines.get(3));
}
@Test
public void readLinesUsingFileReader2() throws IOException {
List<String> lines = readLinesUsingFileReader(txt2);
Assert.assertTrue(lines.isEmpty());
}
@测试
public void readLinesUsingFileReader0()引发IOException{
列表行=readLinesUsingFileReader(txt0);
Assert.assertEquals(3,line.size());
Assert.assertEquals(“Hello”,lines.get(0));
Assert.assertEquals(“,”,line.get(1));
Assert.assertEquals(“World!”,lines.get(2));
}
@试验
public void readLinesUsingFileReader1()引发IOException{
列表行=readlineusingfilereader(txt1);
Assert.assertEquals(4,line.size());
Assert.assertEquals(“,line.get(0));
Assert.assertEquals(“,line.get(1));
Assert.assertEquals(“,line.get(2));
Assert.assertEquals(“,line.get(3));
}
@试验
public void readLinesUsingFileReader2()引发IOException{
列表行=readLinesUsingFileReader(txt2);
Assert.assertTrue(lines.isEmpty());
}
您必须逐字符读取内容,并解析新行序列
新行序列可以是以下任意一种:
public List<String> readLinesUsingFileReader(String filename) throws IOException {
List<String> lines = null;
try (FileReader fileReader = new FileReader(filename)) {
lines = readLines(fileReader);
}
return lines;
}
private List<String> readLines(FileReader fileReader) throws IOException {
List<String> lines = new ArrayList<>();
boolean newLine = false;
int c, p = 0;
StringBuilder line = new StringBuilder();
while(-1 != (c = fileReader.read())) {
if(c == '\n' && p != '\r') {
newLine = true;
} else if(c == '\r') {
newLine = true;
} else {
if(c != '\n' && c != '\r') {
line.append((char) c);
}
}
if(newLine) {
lines.add(line.toString());
line = new StringBuilder();
newLine = false;
}
p = c;
}
if(line.length() > 0) {
lines.add(line.toString());
}
return lines;
}
'\r'
'\n'
“\r\n”
public List<String> readLinesUsingFileReader(String filename) throws IOException {
List<String> lines = null;
try (FileReader fileReader = new FileReader(filename)) {
lines = readLines(fileReader);
}
return lines;
}
private List<String> readLines(FileReader fileReader) throws IOException {
List<String> lines = new ArrayList<>();
boolean newLine = false;
int c, p = 0;
StringBuilder line = new StringBuilder();
while(-1 != (c = fileReader.read())) {
if(c == '\n' && p != '\r') {
newLine = true;
} else if(c == '\r') {
newLine = true;
} else {
if(c != '\n' && c != '\r') {
line.append((char) c);
}
}
if(newLine) {
lines.add(line.toString());
line = new StringBuilder();
newLine = false;
}
p = c;
}
if(line.length() > 0) {
lines.add(line.toString());
}
return lines;
}
使用创建的文件进行测试
@Test
public void readLinesUsingFileReader0() throws IOException {
List<String> lines = readLinesUsingFileReader(txt0);
Assert.assertEquals(3, lines.size());
Assert.assertEquals("Hello", lines.get(0));
Assert.assertEquals(",", lines.get(1));
Assert.assertEquals("World!", lines.get(2));
}
@Test
public void readLinesUsingFileReader1() throws IOException {
List<String> lines = readLinesUsingFileReader(txt1);
Assert.assertEquals(4, lines.size());
Assert.assertEquals("", lines.get(0));
Assert.assertEquals("", lines.get(1));
Assert.assertEquals("", lines.get(2));
Assert.assertEquals("", lines.get(3));
}
@Test
public void readLinesUsingFileReader2() throws IOException {
List<String> lines = readLinesUsingFileReader(txt2);
Assert.assertTrue(lines.isEmpty());
}
@测试
public void readLinesUsingFileReader0()引发IOException{
列表行=readLinesUsingFileReader(txt0);
Assert.assertEquals(3,line.size());
Assert.assertEquals(“Hello”,lines.get(0));
Assert.assertEquals(“,”,line.get(1));
Assert.assertEquals(“World!”,lines.get(2));
}
@试验
public void readLinesUsingFileReader1()引发IOException{
列表行=readlineusingfilereader(txt1);
Assert.assertEquals(4,line.size());
Assert.assertEquals(“,line.get(0));
Assert.assertEquals(“,line.get(1));
Assert.assertEquals(“,line.get(2));
Assert.assertEquals(“,line.get(3));
}
@试验
public void readLinesUsingFileReader2()引发IOException{
列表行=readLinesUsingFileReader(txt2);
Assert.assertTrue(lines.isEmpty());
}
如果您有新行字符
public static void main(String[]args) throws IOException{
FileReader in = new FileReader("D:/test.txt");
char [] a = new char[50];
in.read(a); // reads the content to the array
for(char c : a)
System.out.print(c); //prints the characters one by one
in.close();
}
它会打印出来
Hello
Java
如果你有新行字符
public static void main(String[]args) throws IOException{
FileReader in = new FileReader("D:/test.txt");
char [] a = new char[50];
in.read(a); // reads the content to the array
for(char c : a)
System.out.print(c); //prints the characters one by one
in.close();
}
它会打印出来
Hello
Java
我认为这个版本的代码不会打印“你好” 您的电话是:
int line = in.read();
这有什么用?在Javadocs中查找阅读器
:
公共int read()
抛出IOException
读取单个字符。此方法将一直阻止,直到字符可用、发生I/O错误或结束
到了小溪的尽头
(强调矿山)
您的代码从'Hello'中读取'H',这是ASCII码中的72
然后它进入循环,行==72,因此它进入循环:
for(int i=0;i<line;i++)
这不是你想要的:
- 您不希望循环重复,直到i>=“我刚读到的字符”。您希望它重复执行,直到.read()中的
返回
。您可能已经学会了如何循环直到满足条件-1
- 您不想
每个字符,因为这会添加您不想要的换行符。使用println()
print()
Reader.read(byte[]buffer)
方法,看看是否可以编写更大块的代码
在编程生涯中,您将反复使用的两种模式是:
Type x = getSomehow();
while(someCondition(x)) {
doSomethingWith(x);
x = getSomehow();
}
。。。而且
Type x = value_of_x_which_meets_condition;
while(someCondition(x)) {
x = getSomehow();
doSomethingWith(x);
}
看看你是否能用
文件阅读器和你从中得到的值来构建一些东西,填入“somehows”。我认为这个版本的代码不会打印“Hello”
您的电话是:
int line = in.read();
这有什么用?在Javadocs中查找阅读器
:
公共int read()
抛出IOException
读取单个字符。此方法将一直阻止,直到字符可用、发生I/O错误或结束
到了小溪的尽头
(强调矿山)
您的代码从'Hello'中读取'H',这是ASCII码中的72
然后它进入循环,行==72,因此它进入循环:
for(int i=0;i<line;i++)
这不是你想要的:
- 您不希望循环重复,直到i>=“我刚读到的字符”。您希望它重复执行,直到.read()中的
返回-1
。您可能已经学会了如何循环直到满足条件
- 您不想
println()
每个字符,因为这会添加您不想要的换行符。使用print()
您还应该查看Reader.read(byte[]buffer)
方法,看看是否可以编写更大块的代码
在编程生涯中,您将反复使用的两种模式是:
Type x = getSomehow();
while(someCondition(x)) {
doSomethingWith(x);
x = getSomehow();
}
。。。而且
Type x = value_of_x_which_meets_condition;
while(someCondition(x)) {
x = getSomehow();
doSomethingWith(x);
}
查看是否可以使用FileReader
和从中获得的值构造某些内容,并填写“somehows”。Reader.read()返回单字符的int代码,如果到达文件末尾,则返回-1:
因此,逐字符读取文件,并检查LF(换行符,'\n',0x0A,十进制为10)、CR(回车符,'\r',0x0D,十进制为13)和行尾代码
注意:Windows操作系统使用2个字符对行末尾进行编码:“\r\n”。大多数其他系统,包括Linux、MacOS等,仅使用“\n”对行尾进行编码
final StringBuilder line = new StringBuilder(); // line buffer
try (FileReader in = new FileReader("D:/test.txt")) {
int chAr, prevChar = 0x0A; // chAr - just read char, prevChar - previously read char
while (prevChar != -1) { // until the last read char is EOF
chAr = in.read(); // read int code of the next char
switch (chAr) {
case 0x0D: // CR - just
break; // skip
case -1: // EOF
if (prevChar == 0x0A) {
break; // no need a new line if EOF goes right after LF
// or no any chars were read before (prevChar isn't
// changed from its initial 0x0A)
}
case 0x0A: // or LF
System.out.println("line:" + line.toString()); // get string from the line buffer
line.setLength(0); // cleanup the line buffer
break;
default: // if any other char code is read
line.append((char) chAr); // append to the line buffer
}
prevChar = chAr; // remember the current char as previous one for the next iteration
}
}
Reader.read()