Исключение NullPointerException с использованием библиотеки Apache bzip2

#java

#java

Вопрос:

Я использую библиотеку сжатия BZip2 от Apache Ant. Документация приведена по адресу — http://javadoc.haefelinger.it/org.apache.ant/1.7.1/org/apache/tools/bzip2/CBZip2InputStream.html

Я продолжаю получать эту ошибку при запуске кода —

    Exception in thread "main" java.lang.NullPointerException
    at org.apache.tools.bzip2.CBZip2InputStream.bsR(CBZip2InputStream.java:323)
    at org.apache.tools.bzip2.CBZip2InputStream.bsGetUChar(CBZip2InputStream.java:341)
    at org.apache.tools.bzip2.CBZip2InputStream.initBlock(CBZip2InputStream.java:230)
    at org.apache.tools.bzip2.CBZip2InputStream.<init>(CBZip2InputStream.java:178)
    at org.apache.tools.bzip2.bzipCompression.main(bzipCompression.java:37)
  

Ошибка в строке —

 **CBZip2InputStream cin = new CBZip2InputStream(fileInputStream);**
  

Мой исходный код —

   public static void main(String[] args) throws IOException, NullPointerException {
    // TODO Auto-generated method stub

    FileReader inFile = new FileReader("alice29.txt");
    BufferedReader buff = new BufferedReader(inFile);

    FileOutputStream fout = new FileOutputStream("alicea.txt");
    fout.write("BZ".getBytes());


    CBZip2OutputStream czout = new CBZip2OutputStream (fout);

    String message = buff.readLine(); // read first line

    while(message!=null){
        byte[] input = message.getBytes();
        czout.write(input);
        message = buff.readLine();
    }
    czout.flush();
    czout.close();


    InputStream fileInputStream = new FileInputStream("alicea.txt");
    CBZip2InputStream cin = new CBZip2InputStream(fileInputStream);
    FileOutputStream decOut = new FileOutputStream("decompressedAlice.txt");


    byte[] buf = new byte[100000];
    int len;

    while((len = cin.read(buf))>0){
        decOut.write(buf, 0, len);
    }
    decOut.close();
    cin.close();

}
  

Большое спасибо за вашу помощь.

Комментарии:

1. Что мешает вам установить точку останова в NPE (или строку 323 CBZip2InputStream), чтобы точно определить, какая переменная — скорее всего, член CBZip2InputStream — равна null? Это должно дать вам некоторые подсказки, а не нам гадать.

Ответ №1:

Вы открываете FileOutputStream для alicea.txt

 FileOutputStream fout = new FileOutputStream("alicea.txt");
  

Этот выходной поток никогда не закрывается в вашем коде, но в строке ошибки вы открываете FileInputStream в том же файле:

 InputStream fileInputStream = new FileInputStream("alicea.txt");
CBZip2InputStream cin = new CBZip2InputStream(fileInputStream);
  

ИМХО, пока у вас открыт FileOutputStream в файле, вы не можете открыть file InputStream в том же файле. Это может быть причиной, по которой ваш FileInputStream равен NULL и генерируется исключение.

Обновление: В CBZip2InputStream есть известная ошибка и решение, описанное в 2002 году (все еще можно найти на MarkMail), которое все еще существует. Вы должны загрузить java-классы и можете не использовать готовый архив build .jar. Измените следующие строки в методе initialize() для CBZip2InputStream.java:

Исходный код (начиная со строки 213):

 private void initialize() {
    char magic3, magic4;
    magic3 = bsGetUChar();
    magic4 = bsGetUChar();
    if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
        bsFinishedWithStream();
        streamEnd = true;
        return;
    }
    setDecompressStructureSizes(magic4 - '0');
    computedCombinedCRC = 0;
}
  

Измените это на:

 private void initialize() {
    char magic1, magic2; 
    char magic3, magic4; 
    magic1 = bsGetUChar(); 
    magic2 = bsGetUChar(); 
    magic3 = bsGetUChar(); 
    magic4 = bsGetUChar(); 
    if (magic1 != 'B' || magic2 != 'Z' | magic3 != 'h' || magic4 < '1' || magic4 > '9') {   
        bsFinishedWithStream();
        streamEnd = true;
        return;
    }
    setDecompressStructureSizes(magic4 - '0');
    computedCombinedCRC = 0;
}
  

Последнее обновление:
Я только что просмотрел svn apache ant; ошибка в trunk исправлена. Но, несмотря на этот факт, многие, очень многие загрузки все еще содержат эту ошибку. Я также случайно скачал только старую версию, чтобы проверить вашу проблему.

Комментарии:

1. @Erik: «пока у вас открыт FileOutputStream в файле, вы не можете открыть file InputStream в том же файле» — не могли бы вы предоставить ссылку на то, почему это может быть правдой?

2. Я добавил fout.close(); а также изменил разрешения alicea.txt для чтения, записи и выполнения. но это не решило проблему: (

3. @aix: попытается найти ссылку для вас. Но я никогда не видел этого в своей жизни. Обычно вы открываете один filedescriptor для одного файла из одного экземпляра, а не из нескольких.

4. @Erik — CBZip2OutputStream сожмет файл, и я действительно вижу сжатый файл в моем каталоге. Имя сжатого файла является alicea.txt. На втором шаге я пытаюсь распаковать файл и посмотреть, точно ли содержимое распакованного файла совпадает с содержимым исходного файла — alice29.txt Я думаю, что CBZip2InputStream должен распаковывать файл

5. @Ashish Agarwal было бы здорово с вашей стороны принять мой ответ в качестве решения (установите эту галочку под счетчиком моего ответа), чтобы другие могли видеть, что на вопрос дан ответ.