Counting the size of a text file in java while writing to the file

5.2k Views Asked by At

This question is a follow up to the accepted answer in this question. I am trying to implement the approach suggested by Aaron : Wrapping the FileOutputStream to include the logic to keep a count of the no.of bytes written so far. However the approach quite doesn't seem to work as expected. The OutputStreamWriter seems to be using a StreamEncoder which is buffering the data before delegating call to the FileOutputStream.write() method.

Here is a small Demo :

package Utils;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MyFileOutputStream extends FileOutputStream{

private int byteCount;
public int getByteCount() {
    return byteCount;
}

public void setByteCount(int byteCount) {
    this.byteCount = byteCount;
}

public MyFileOutputStream(String arg0) throws FileNotFoundException {
    super(arg0);
    byteCount = 0;
}

@Override
public void write(byte[] b) throws IOException{
    byteCount += b.length;
    super.write(b);
}

@Override
public void write(byte[] b , int off , int len) throws IOException{
    byteCount += len;
    super.write(b, off, len);
}
}

And Driver Class :

  package main;
  import java.io.BufferedWriter;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.io.Writer;

  import Utils.MyFileOutputStream;

  public class Driver {

/**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {
    MyFileOutputStream fos = new MyFileOutputStream("testFile");
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
    for(int i=0;i<1000;i++){
        bw.write("Writing this string\n");
        System.out.println("Bytes Written : "+fos.getByteCount());
    }
    bw.close();
    System.out.println(fos.getByteCount());
}

}

Output :-

Bytes Written : 0
Bytes Written : 0
...
Bytes Written : 8192
Bytes Written : 8192
...

As shown by the output the StreamEncoder buffers up to 8192 bytes before delegating call to write() method of FileOutputStream. Is there any work around for this to get the no.of bytes written to a file at any instant of time ?

3

There are 3 best solutions below

4
On

Is there any work around for this to get the no.of bytes written to a file at any instant of time ?

That's what you're getting. The number of bytes that have been written to the file.

What you really seem to be asking for is the number of chars that have been written to the BufferedWriter. In which case what you need to do is wrap/extend the BufferedWriter.

0
On

You can flush() the outermost writer/stream. That forces BufferedWriter to convert all the characters in its buffer to bytes and send them to the underlying FileOutputStream.

Note that this is a somewhat expensive operation: It will not only convert the bytes but actually write them to the disk. So if you call flush() too often, that will be bad for overall performance.

Another option would be to reduce the buffer size to, say, 128. That would cause 64 times the IO but give a more fine grained picture.

If performance is a problem, then you need to move the buffering further down. Directly write to the OutputStreamWriter and wrap the FileOutputStream in a class which extends BufferedOutputStream.

That way, the characters will converted to bytes immediately and added to the buffer in BufferedOutputStream. Now you just need to ask your BufferedOutputStream how many bytes it has written to the FileOutputStream + this.count.

0
On

How about CountingOutputStream? It will solve your problem easily.