2

When I used the method of workWithFileReader(),try to get the how many char in this document,and get the result : 547. And When I used the method of workWithBufferedReader(),try to get the how many char in this document,and get the result : 526.

I'm not sure which correct,so I used the word to get the char(include space),and get the answer :526.

Please help to example the different between them.

public static void workWithFileReader() {
        int i;
        long len;               //
        int countChar = 0;      //read byte +1
        int countLine = 0;      //get char(10) +1

        File file = new File("/Users/wayne/Downloads/Sample.txt");
        len=file.length();
        try {
            FileReader fr = new FileReader(file);
            //len = fr.available();
            while((i=fr.read()) != -1) {
                System.out.print((char)i);
                countChar++;
                if((char) i == 10) {
                    countLine++;
                }
            }

            System.out.println("----------------------");
            System.out.println("共有"+len+"個位元組");
            System.out.println("共有"+countChar+"個字元");
            System.out.println("共有"+countLine+"列資料");

            fr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }

    public static void workWithBufferedReader() {

        String str;

        long len;
        int countChar = 0;
        int countLine = 0;


        File file = new File("/Users/wayne/Downloads/Sample.txt");
        len = file.length();
        try {
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);

            while((str=br.readLine()) != null) {
                System.out.println(str);
                countChar += str.length(); 
                countLine++;     
            }

            System.out.println("----------------------");
            System.out.println("共有"+len+"個位元組");
            System.out.println("共有"+countChar+"個字元");
            System.out.println("共有"+countLine+"列資料");


            br.close();
            fr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }
firephil
  • 830
  • 10
  • 18
  • 1
    Like always, reading documentation helps. What does the JavaDoc for `readline` say? **"not including any line-termination characters"**, `FileReader#read` doesn't exclude line breaks. A bit strange is .. you know this difference, because you explicitly count and handle a certain line break `if((char) i == 10)` – Tom Mar 25 '19 at 12:14
  • @Tom ,Hi thanks your answer,but ` if((char) i == 10) { countLine++; }` ,this will get 10 line ,so 526+10 < 547, and there have any way to get the line-termination characters that `readline` didn't including? I only konw char(10) meaning \n. – Wayne Chiang Mar 25 '19 at 12:35
  • No. There isn't a way. The line terminator is consumed and there is no way to know for sure what it was. (You can infer the line separator from the platform ... but your inference may be incorrect!) – Stephen C Mar 25 '19 at 13:06
  • Not a duplicate, just a code bug... – firephil Mar 25 '19 at 13:26
  • Your code only counts "10", which is `\n` like you said, but there is also "13" for "carriage return", used by Window file line encondings. So if you have 10 lines, then these are additional chars. – Tom Mar 25 '19 at 14:14

2 Answers2

0

workWithFileReader() counts all characters including newline "\n" and "\r" carriage return.

In Windows OS file lines are terminated with two characters "\r" and "\n" The characters you are missing are those.

In unix based OS Linux,Mac,BSD etc lines are terminated with just "\n" You need to be aware this subtle difference.

workWithFileReader() counts only the characters that are included inside the lines without the terminating characters "\r" and "\n"

Here is an example File with the "\r" and "\n" visible: enter image description here

Be aware also that Count has to start from 1 not 0 when you reach the first "\n" you have 2 lines.

You can use the following as a reference :

package io;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class IO {

    public static void main(String[] args) throws IOException {
        String path = "C:\\1.txt";

        List<String> readAllLines = Files.readAllLines(Paths.get(path));
        System.out.println("lines: " + readAllLines.size());

        byte[] bytes = Files.readAllBytes(Paths.get(path));
        String s = new String(bytes);
        System.out.println("characters:" + s.length());
    }
}
firephil
  • 830
  • 10
  • 18
0

I check the JAVADOC and got the readline,
it's saying...This method recognizes the following as line terminators:

\u000D followed by \u000A, CARRIAGE RETURN followed by LINE FEED \u000A, LINE FEED \u000D, CARRIAGE RETURN

So , I verify this...

                if((char) i == 10) {
                    countLine++;
                    lineTerminators++;
                }

                if((char) i == 13) {
                    countLine++;
                    lineTerminators++;
                }

And yes! lineTerminators got the 21, 547-526=21.

  • its good practise not to answer your own question and edit your question and add [edit] to show it. Also give credit to the answer that helped you to realize the error :) – firephil Mar 28 '19 at 13:52