简体   繁体   English

读取文件位并保存它们

[英]Reading files bits and saving them

i have file reader which read entire file and write it's bits. 我有读取整个文件并将其写入的文件读取器。 I have this class which help reading: 我有这节课,可以帮助阅读:

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

}

In class where i call this, i do: 在我称之为的课堂上,我这样做:

FileInputStream inputStream = new FileInputStream(file);

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

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

        FileReader bitIn = new FileReader(fileBits);      

and this work correctly. 并且可以正常工作。 However i have problems with big files above 100 mb because byte[] have the end. 但是我对100 mb以上的大文件有问题,因为byte []结尾。

So i want to read bigger files. 所以我想阅读更大的文件。 Maybe some could suggest how i can improve this code ? 也许有人可以建议我如何改进此代码?

Thanks. 谢谢。

org.apache.commons.io.IOUtils.copy(InputStream in, OutputStream out)

If scaling to large file sizes is important, you'd be better off not reading the entire file into memory. 如果缩放到大文件很重要,最好不要将整个文件读到内存中。 The downside is that handling the IOException in more locations can be a little messy. 缺点是在更多位置处理IOException可能会有些混乱。 Also, it doesn't look like your application needs something that implements the InputStream API, it just needs the readBit() method. 另外,看起来您的应用程序不需要实现InputStream API的东西,而只需要readBit()方法。 So, you can safely encapsulate, rather than extend, the InputStream . 因此,您可以安全地封装而不是扩展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;
  }

}

Usage would look similar. 用法看起来类似。

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

If you really do want to read in the entire file, and you are working with an actual file, you can query the length of the file first. 如果您确实确实想读取整个文件,并且正在使用实际文件,则可以先查询文件的长度。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM