2012-02-22 3 views
1

У меня есть считыватель файлов, которые читают весь файл и записывают его биты. У меня есть этот класс, который поможет чтение:Чтение битов файлов и их сохранение

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 мб, потому что байт [] имеет конец.

Так что я хочу читать большие файлы. Может быть, некоторые могли бы предложить, как я могу улучшить этот код?

Спасибо.

+1

Не использовать имеющиеся(). Не игнорируйте результат вызова read(). Доступный() не возвращает размер файла. И read() не обязательно читает все сразу. –

+0

Не называйте его 'FileReader', если он не реализует' java.io.Reader', а также не потому, что он конфликтует с 'java.io.FileReader'. –

+0

Благодарим за отзыв – Streetboy

ответ

0

Если важно масштабирование до больших размеров файлов, вам лучше не читать весь файл в памяти. Недостатком является то, что обработка IOException в других местах может быть немного грязной. Кроме того, это не похоже, что вашему приложению требуется что-то, что реализует API InputStream, ему просто нужен метод 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(); 
} 
+0

В приведенном выше коде int int = src.read (bits); Я получаю исключение – Streetboy