4

这个问题是对这个问题中接受的答案的跟进。我正在尝试实施 Aaron 建议的方法:包装 FileOutputStream 以包含逻辑以记录迄今为止写入的字节数。然而,这种方法似乎并没有按预期工作。OutputStreamWriter 似乎正在使用StreamEncoder,它在委托调用 FileOutputStream.write() 方法之前缓冲数据。

这是一个小演示:

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);
}
}

和驱动程序类:

  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());
}

}

输出 :-

写入字节数:0
写入字节数:0
...
写入字节数:8192
写入字节数:8192
...

如输出所示,StreamEncoder 在委托调用 FileOutputStream 的 write() 方法之前最多缓冲 8192 个字节。是否有任何解决方法可以在任何时刻将字节数写入文件?

4

3 回答 3

1

是否有任何解决方法可以在任何时刻将字节数写入文件?

这就是你得到的。已写入文件的字节数。

您真正要求的是已写入BufferedWriter. 在这种情况下,您需要做的是包装/扩展BufferedWriter.

于 2014-05-04T04:43:49.117 回答
1

你可以flush()最外层的作家/流。这会强制BufferedWriter将其缓冲区中的所有字符转换为字节并将它们发送到底层FileOutputStream

请注意,这是一个有点昂贵的操作:它不仅会转换字节,还会将它们实际写入磁盘。所以如果你打电话flush()太频繁,那将不利于整体性能。

另一种选择是将缓冲区大小减少到 128。这将导致 64 倍的 IO,但会提供更细粒度的图片。

如果性能是一个问题,那么您需要进一步降低缓冲。直接写入OutputStreamWriter并将 包装FileOutputStream在扩展的类中BufferedOutputStream

这样,字符将立即转换为字节并添加到BufferedOutputStream. 现在您只需要询问BufferedOutputStream它已写入FileOutputStream+的字节数this.count

于 2014-05-09T14:24:54.870 回答
1

CountingOutputStream怎么样?它将轻松解决您的问题。

于 2020-11-13T12:19:41.037 回答