java - 读取文件位并保存它们

标签 java huffman-code

我有文件阅读器,可以读取整个文件并写入它的位。 我有这个类(class)可以帮助阅读:

import java.io.*;

public class FileReader extends ByteArrayInputStream{

  private int bitsRead;
  private int bitPosition;
  private int currentByte;
  private int myMark;
  private final static int NUM_BITS_IN_BYTE = 8;
  private final static int END_POSITION = -1;
  private boolean readingStarted;
  /**
   * Create a BitInputStream for a File on disk.
   */
  public FileReader( byte[] buf ) throws IOException {
    super( buf );

    myMark         = 0;
    bitsRead       = 0;
    bitPosition    = NUM_BITS_IN_BYTE-1;
    currentByte    = 0;
    readingStarted = false;
  }


  /**
   * Read a binary "1" or "0" from the File.
   */
  public int readBit() throws IOException {
    int theBit = -1;

    if( bitPosition == END_POSITION || !readingStarted ) {
      currentByte    = super.read();
      bitPosition    = NUM_BITS_IN_BYTE-1;
      readingStarted = true;
    }

    theBit = (0x01 << bitPosition) & currentByte;
    bitPosition--;

    if( theBit > 0 ) {
      theBit = 1;
    }

    return( theBit );
  }


  /**
   * Return the next byte in the File as lowest 8 bits of int.
   */
  public int read() {
    currentByte    = super.read();
    bitPosition    = END_POSITION;
    readingStarted = true;

    return( currentByte );
  }


  /**
   *
   */
  public void mark( int readAheadLimit ) {
    super.mark(readAheadLimit);
    myMark = bitPosition;
  }


  /**
   * Add needed functionality to super's reset() method. Reset to
   * the last valid position marked in the input stream.
   */
  public void reset() {
    super.pos   = super.mark-1;
    currentByte = super.read();
    bitPosition = myMark;
  }


  /**
   * Returns the number of bits still available to be read.
   */
  public int availableBits() throws IOException {
    return(  ((super.available() * 8) + (bitPosition + 1))  );
  }

}

在我称之为这个的类里面,我这样做:

FileInputStream inputStream = new FileInputStream(file);

        byte[] fileBits = new byte[inputStream.available()];

        inputStream.read(fileBits, 0, inputStream.available());
        inputStream.close();

        FileReader bitIn = new FileReader(fileBits);      

并且这可以正常工作。 但是,我在处理超过 100 mb 的大文件时遇到问题,因为 byte[] 有结尾。

所以我想读取更大的文件。也许有人可以建议我如何改进这段代码?

谢谢。

最佳答案

如果缩放到大文件大小很重要,那么最好不要将整个文件读入内存。缺点是在更多位置处理 IOException 可能会有点困惑。此外,您的应用程序似乎不需要实现 InputStream API 的东西,它只需要 readBit() 方法。因此,您可以安全地封装(而不是扩展)InputStream

class FileReader {

  private final InputStream src;

  private final byte[] bits = new byte[8192];

  private int len;

  private int pos;

  FileReader(InputStream src) { 
    this.src = src; 
  }

  int readBit() throws IOException {
    int idx = pos / 8;
    if (idx >= len) {
      int n = src.read(bits);
      if (n < 0)
        return -1;
      len = n;
      pos = 0;
      idx = 0;
    }
    return ((bits[idx] & (1 << (pos++ % 8))) == 0) ? 0 : 1;
  }

}

用法看起来很相似。

FileInputStream src = new FileInputStream(file);
try {
  FileReader bitIn = new FileReader(src);
  ...
} finally {
  src.close();
}

如果您确实想读取整个文件,并且正在处理实际文件,则可以先查询文件的长度。

File file = new File(path);
if (file.length() > Integer.MAX_VALUE)
  throw new IllegalArgumentException("File is too large: " + file.length());
int len = (int) file.length();
FileInputStream inputStream = new FileInputStream(file);
try { 
  byte[] fileBits = new byte[len];
  for (int pos = 0; pos < len; ) {
    int n = inputStream.read(fileBits, pos, len - pos);
    if (n < 0)
      throw new EOFException();
    pos += n;
  }
  /* Use bits. */
  ...
} finally {
  inputStream.close();
}

关于java - 读取文件位并保存它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9401931/

相关文章:

java - 将 `java.sql.blob` 转换为 `javax.xml.transform.stream.StreamSource`

java - 带有自定义 View 的 ScrollView 不会滚动 - android?

C# - 对大文件进行霍夫曼编码需要太长时间

java - 打印霍夫曼频率表

java - 如何使用 Eclipse 内存分析器工具 (MAT) 分析 HashMap

java - 局部变量可能已经被赋值

c - 使用霍夫曼编码的文本数据压缩

c++ - SHLD+BSR解码器?

python - 是否可以使用 '0' 和 '1' 字符构建霍夫曼算法?

java - 如何在我的 Web 应用程序中使用 OpenStack 组件