Shafu
Shafu

Reputation: 41

getting the progress of reading file

This is a part of my java code, I want to get the number of bytes read from the file, I increase 4 bytes in each loop cycle because the size of an integer is 4 bytes, but this code is not working properly, the loop of this code runs beyond the size of file. Please solve the problem.

import java.io.File;
import java.util.Scanner;



public class S {


    public S() throws Exception {

        Scanner sc = new Scanner(new File("file.txt"));

        for(int i=0; sc.hasNext(); i+=4) {
            sc.nextInt();
            System.out.println("Read = "+i+" bytes");
        }

        System.out.println("done");
    }


    public static void main(String arg[]) throws Exception {
        new S();
    }

}

Upvotes: 0

Views: 321

Answers (1)

slartidan
slartidan

Reputation: 21608

A Scanner is not made for such use cases. The scanner will read more data than it currently uses - if you track the bytes written, than you will get other results as expected:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;



public class S {


    private final static class ProgressStream extends FileInputStream {
        private int bytesRead;

        private ProgressStream(File file) throws FileNotFoundException {
            super(file);
        }

        @Override
        public int read() throws IOException {
            int b = super.read();
            if (b != -1)
                bytesRead++;
            return b;
        }

        @Override
        public int read(byte[] b) throws IOException {
            int read = super.read(b);
            if (read != -1)
                bytesRead += read;
            return read;
        }

        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            int read = super.read(b, off, len);
            if (read != -1)
                bytesRead += read;
            return read;
        }
    }

    public S() throws Exception {

        ProgressStream progressStream = new ProgressStream(new File("file.txt"));

        Scanner sc = new Scanner(progressStream);

        while (sc.hasNext()) {
            sc.nextInt();
            System.out.println("Read = " + progressStream.bytesRead + " bytes");
        }

        System.out.println("done");
    }


    public static void main(String arg[]) throws Exception {
        new S();
    }

}

For Input-File

123 456   789

It outputs

Read = 13 bytes
Read = 13 bytes
Read = 13 bytes
done

So you will have to implement a scanner-like functionality by your own...

import java.io.File;
import java.io.FileInputStream;



public class S {

    public S() throws Exception {

        FileInputStream stream = new FileInputStream(new File("file.txt"));

        int b;
        StringBuilder lastDigits = new StringBuilder();
        int read = 0;
        while ((b = stream.read()) != -1) {
            read++;
            char c = (char) b;
            if (Character.isDigit(c)) {
                lastDigits.append(c);
            } else if (lastDigits.length() > 0) {
                System.out.println("found int "+Integer.parseInt(lastDigits.toString()));
                System.out.println("Read = "+read+" bytes");
                lastDigits = new StringBuilder();
            }
        }

        if (lastDigits.length() > 0) {
            System.out.println("found int "+Integer.parseInt(lastDigits.toString()));
            System.out.println("Read = "+read+" bytes");
        }

        System.out.println("done");
    }


    public static void main(String arg[]) throws Exception {
        new S();
    }

}

will output

found int 123
Read = 4 bytes
found int 456
Read = 8 bytes
found int 789
Read = 13 bytes
done

Upvotes: 1

Related Questions