Java 为什么在尝试读取文件时会出现 NullPointerException?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/703231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:32:15  来源:igfitidea点击:

Why am I getting a NullPointerException when trying to read a file?

javafile-ioitext

提问by

I use this test to convert txt to pdf :

我使用此测试将 txt 转换为 pdf :

package convert.pdf;

//getResourceAsStream(String name) : Returns an input stream for reading the specified resource.
//toByteArray : Get the contents of an InputStream as a byte[].

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;

import convert.pdf.txt.TextConversion;

public class TestConversion {

  private static byte[] readFilesInBytes(String file) throws IOException {
      return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
  }

  private static void writeFilesInBytes(byte[] file, String name) throws IOException {
      IOUtils.write(file, new FileOutputStream(name));
  }

  //just change the extensions and test conversions
  public static void main(String args[]) throws IOException {
      ConversionToPDF algorithm = new TextConversion();
      byte[] file = readFilesInBytes("/convert/pdf/text.txt");
      byte[] pdf = algorithm.convertDocument(file);
      writeFilesInBytes(pdf, "text.pdf");
  }

}

Problem:

问题:

Exception in thread "main" java.lang.NullPointerException
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
    at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
    at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:218)
    at convert.pdf.TestConversion.readFilesInBytes(TestConversion.java:17)
    at convert.pdf.TestConversion.main(TestConversion.java:28)

I use the debugger, and the problem seems to be located here :

我使用调试器,问题似乎出在这里:

  private static byte[] readFilesInBytes(String file) throws IOException {
      return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
  }

What is my problem?

我的问题是什么?

回答by Eddie

Are you checking to see if the file exists before you pass it to readFilesInBytes()? Note that Class.getResourceAsStream()returns nullif the file cannot be found. You probably want to do:

您是否在将文件传递给之前检查该文件是否存在readFilesInBytes()?请注意,如果找不到文件,则Class.getResourceAsStream()返回null。你可能想做:

private static byte[] readFilesInBytes(String file) throws IOException {
  File testFile = new File(file);
  if (!testFile.exists()) {
      throw new FileNotFoundException("File " + file + " does not exist");
  }
  return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}

or better yet:

或者更好:

private static byte[] readFilesInBytes(String file) throws IOException {
  InputStream stream = TestConversion.class.getResourceAsStream(file);
  if (stream == null) {
      throw new FileNotFoundException("readFilesInBytes: File " + file
                                      + " does not exist");
  }
  return IOUtils.toByteArray(stream);
}

回答by Jon Skeet

Sounds like the resource probably doesn't exist with that name.

听起来该资源可能不存在该名称。

Are you aware that Class.getResourceAsStream()finds a resource relative to that class's package, whereas ClassLoader.getResourceAsStream()doesn't? You can use a leading forward slash in Class.getResourceAsStream()to mimic this, so

您是否知道Class.getResourceAsStream()找到与该类的包相关的资源,而ClassLoader.getResourceAsStream()没有?您可以使用前导斜杠Class.getResourceAsStream()来模仿这一点,所以

Foo.class.getResourceAsStream("/bar.png")

is roughly equivalent to

大致相当于

Foo.class.getClassLoader().getResourceAsStream("bar.png")

Is this actuallya file (i.e. a specific file on the normal file system) that you're trying to load? If so, using FileInputStreamwould be a better bet. Use Class.getResourceAsStream()if it's a resource bundled in a jar file or in the classpath in some other way; use FileInputStreamif it's an arbitrary file which could be anywhere in the file system.

实际上是您尝试加载的文件(即普通文件系统上的特定文件)吗?如果是这样,使用FileInputStream将是更好的选择。Class.getResourceAsStream()如果它是以其他方式捆绑在 jar 文件或类路径中的资源,请使用;FileInputStream如果它是可以位于文件系统中任何位置的任意文件,请使用。

EDIT: Another thing to be careful of, which has caused me problems before now - if this has worked on your dev box which happens to be Windows, and is now failing on a production server which happens to be Unix, check the case of the filename. The fact that different file systems handle case-sensitivity differently can be a pain...

编辑:另一件要小心的事情,这之前已经给我带来了问题 - 如果这在您的开发箱上工作,恰好是 Windows,并且现在在恰好是 Unix 的生产服务器上失败,请检查文档名称。不同的文件系统以不同的方式处理区分大小写的事实可能是一个痛苦......

回答by Jon Skeet

This class reads a TXT file in the classpath and uses TextConversion to convert to PDF, then save the pdf in the file system.

该类读取classpath中的一个TXT文件并使用TextConversion转换为PDF,然后将pdf保存在文件系统中。

Here TextConversion code :

这里 TextConversion 代码:

package convert.pdf.txt;
//Conversion to PDF from text using iText.
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import convert.pdf.ConversionToPDF;
import convert.pdf.ConvertDocumentException;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;

public class TextConversion implements ConversionToPDF {

    public byte[] convertDocument(byte[] documents) throws ConvertDocumentException {
        try {
            return this.convertInternal(documents);
        } catch (DocumentException e) {
            throw new ConvertDocumentException(e);
        } catch (IOException e) {
            throw new ConvertDocumentException(e);
        }
    }

    private byte[] convertInternal(byte[] documents) throws DocumentException, IOException {
        Document document = new Document();

        ByteArrayOutputStream pdfResultBytes = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, pdfResultBytes);

        document.open();

        BufferedReader reader = new BufferedReader( new InputStreamReader( new ByteArrayInputStream(documents) ) );

        String line = "";
        while ((line = reader.readLine()) != null) {
            if ("".equals(line.trim())) {
                line = "\n"; //white line
            }
            Font fonteDefault = new Font(Font.COURIER, 10);
            Paragraph paragraph = new Paragraph(line, fonteDefault);
            document.add(paragraph);
        }

        reader.close();

        document.close();

        return pdfResultBytes.toByteArray();
    }
}

And here the code to ConversionToPDF :

这里是 ConversionToPDF 的代码:

package convert.pdf;
// Interface implemented by the conversion algorithms.
public interface ConversionToPDF {

    public byte[] convertDocument(byte[] documentToConvert) throws ConvertDocumentException;
    }

I think the problem come from my file system (devbox on windows and server is Unix). I will try to modify my classpath.

我认为问题来自我的文件系统(Windows 和服务器上的 devbox 是 Unix)。我将尝试修改我的类路径。

回答by He Drunh

This problem may be caused by calling methods on test.txt, which can be a folder shortcut. In other words, you're calling a method on a file that doesn't exist, resulting in a NullPointerException.

此问题可能是由于调用 上的方法引起的test.txt,该方法可以是文件夹快捷方式。换句话说,您正在对不存在的文件调用方法,从而导致NullPointerException.