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;
}
  • 一份cariage退货
    '\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;
    }
    
  • 一份cariage退货
    '\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()