【问题标题】:Counting the size of a text file in java while writing to the file在写入文件时计算java中文本文件的大小
【发布时间】:2014-06-20 14:02:54
【问题描述】:

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

这是一个小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);
}
}

还有驱动类:

  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 个字节。是否有任何解决方法可以在任何时刻将字节数写入文件?

【问题讨论】:

  • 这就是重点,不是吗。 BufferedWriter 缓冲输出直到其内部缓冲区已满,flushclosed 被调用,此时它将缓冲区输出到底层写入器流。
  • 该设计看起来也有些错误(恕我直言),我将创建一个通过 OutputStream 的传递,它采用源 OutputStream。 “计数器”流将覆盖write(int) 并记录通过它的字节数,调用父流的write 方法。这样,您就可以使用您喜欢的任何类型的流...

标签: java io filesize fileoutputstream io-buffering


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可以flush() 最外层的写入器/流。这迫使BufferedWriter 将其缓冲区中的所有字符转换为字节并将它们发送到底层FileOutputStream

    请注意,这是一个有点昂贵的操作:它不仅会转换字节,还会将它们实际写入磁盘。因此,如果您过于频繁地调用flush(),将会影响整体性能。

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      您真正想要的是写入BufferedWriter 的字符数。在这种情况下,您需要做的是包装/扩展BufferedWriter.

      【讨论】:

      • 不,我需要写入文件的字节数,但我不想在 8K 块中得到答案(因为缓冲)。我意识到除了在写入缓冲写入器之前计算字符串的字节数之外别无他法。
      • 你没有得到它。数据写入 8k 块到文件中。 不写入单个字节。 StreamEncoder. 中有缓冲,对此您无能为力。它以较小的部分写入StreamEncoder,但您只能以字符而不是字节来计算。
      • 是的,我明白了。但是,我正在处理使用 UTF-8 编码写入文件的日文汉字字符。因此计算字符不会给出确切的文件大小。因此,我想要字节数。
      • 你明白了。一次 8192 字节。因为这就是 FileOutputStream 正在接收的内容。没有其他答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 2021-04-17
      • 2022-12-12
      • 2011-08-17
      • 1970-01-01
      相关资源
      最近更新 更多