Java写入图像时出现FileNotFoundException异常

3

我正在尝试使用Image.IO.Write()保存一张图片;基本上,我从这里复制了lwjgl截图的标准代码。我所做的唯一一件事是使用现有目录作为保存路径来初始化文件。

当我尝试保存图片时,会抛出FileNotFoundException异常。

    glReadBuffer(GL_FRONT);
    int width  = Display.getDisplayMode().getWidth();
    int height = Display.getDisplayMode().getHeight();
    int bpp = 4; // Assuming a 32-bit display with a byte each for red, green, blue, and alpha.
    ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    File file = new File("res/screenshots/ss_" + Sys.getTime() + ".png"); // The file to save to.
    String format = "PNG"; // Example: "PNG" or "JPG"
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    for(int x = 0; x < width; x++)
        for(int y = 0; y < height; y++)
        {
            int i = (x + (width * y)) * bpp;
            int r = buffer.get(i) & 0xFF;
            int g = buffer.get(i + 1) & 0xFF;
            int b = buffer.get(i + 2) & 0xFF;
            image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
        }

    try {
        ImageIO.write(image, format, file);
    } catch (IOException e) { e.printStackTrace(); }

堆栈跟踪:

java.io.FileNotFoundException: res\screenshots\ss_91733792.png (The system cannot find the path specified)
    at java.io.RandomAccessFile.open(Native Method)
    at java.io.RandomAccessFile.<init>(Unknown Source)
    at javax.imageio.stream.FileImageOutputStream.<init>(Unknown Source)
    at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(Unknown Source)
    at javax.imageio.ImageIO.createImageOutputStream(Unknown Source)
    at javax.imageio.ImageIO.write(Unknown Source)
    at com.va.util.Extras.takeScreenShot(Extras.java:46)
    at com.va.core.Engine.start(Engine.java:117)
    at Main.main(Main.java:26)
Exception in thread "main" java.lang.NullPointerException
    at javax.imageio.ImageIO.write(Unknown Source)
    at com.va.util.Extras.takeScreenShot(Extras.java:46)
    at com.va.core.Engine.start(Engine.java:117)
    at Main.main(Main.java:26)

4
什么问题?你的问题具体是什么? - Ryan
1
展示你的代码...文件部分 - Sully
1
堆栈跟踪也会很有帮助。 - Colin D
3
  1. 确认目录存在且可写。
  2. 确认Java正在写入您认为的目录 - 您程序的工作目录可能是不同的
  3. 如果您不确定,请尝试使用完全限定的路径名(以调试步骤2)。
  4. 确保指定了文件名(以及目录路径)。
  5. 剪切/粘贴实际使用的文件路径。
  6. 剪切/粘贴您看到的准确的堆栈跟踪。
- paulsm4
我之前在两个项目中也使用了这段代码,而且一直运行良好。我尝试检查我的文件夹设置,看起来没问题。我认为可能是处理内部文件的问题。 - coder13
@coder13,“内部文件”是什么?这是目标路径不存在。句号。 - user207421
2个回答

3
我假设"/res/screenshots"文件夹已经存在并且可写,是吗?
我猜测你程序的当前目录可能与你预期的不同。
为了调试,请添加以下两行代码(或等效代码):
  String currentDir = new File(".").getAbsolutePath();
  System.out.println ("Current directory: " + currentDir);

如果"res/screenshots"不在"currentDirectory"下面,则需要在您的代码中更改相对路径。
  // EXAMPLE:
  File file = new File("../..res/screenshots/ss_" + Sys.getTime() + ".png"); 

谢谢。我意识到在我之前的两个项目中完全相同的代码不起作用,因为我是通过链接的项目来运行它的。我有一个主要的和API。代码在API中,并且通过主要运行。主要程序没有建立文件夹,所以这可能就是为什么它不起作用的原因。 - coder13

1

你链接的代码没有展示如何创建文件,而是留给程序员自己去实现。

你所做的可能只是创建了一个新的File对象。

File img = new File("path/to/file.jpg");

您的问题是,path/to 文件夹不存在,而且 ImageIO 抛出了 FileNotFoundException
为了使其正常工作,请使用:
img.getParent().mkdirs();

在将img传递给ImageIO之前,请确保文件的完整路径可访问。正如本帖子的评论中所述,文件本身不必存在,但其路径必须存在。


1
我不确定他需要调用createNewFile()。Javadoc表明它总是会丢弃路径下的任何文件内容。http://docs.oracle.com/javase/1.4.2/docs/api/javax/imageio/ImageIO.html#write%28java.awt.image.RenderedImage,%20java.lang.String,%20java.io.File%29 - Colin D
@Colin D - 我同意。OP不应该需要“createNewFile()”。 - paulsm4
1
谢谢大家。现在OP添加了堆栈跟踪,更明显地看出路径有问题(文件夹不存在)。我已经编辑了原来的答案。 - npe
@npe 完全同意。很好的回答。 - Colin D
不要以为他在错误的位置执行了 "mkdir()" 命令怎么办。而且,为什么每次想要写入新文件时都要调用 "mkdir()" 带来额外的开销?在这种情况下,“mkdir()”不一定是正确的方法... - paulsm4
@paulsm4:嗯,有两种选择。要么他在错误的目录下(请参见 coder13 的答案),要么他假设“截图”文件夹已经存在。我不决定放置 mkdirs() 的位置,但如果他使用许多不同的文件夹,最好调用它。与在 ImageIO#write() 中花费的时间相比,对性能的影响是微不足道的。 - npe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接