Java IO 无法读取输入文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13318912/
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
Java IO can't read input file?
提问by Angus Moore
I have just started learning java and I've been working on this code for a moving object with keyboard input. I am now trying to add in a background, but it keeps erroring with:
我刚刚开始学习 Java,我一直在为带有键盘输入的移动对象编写此代码。我现在正在尝试添加背景,但它不断出错:
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at game.GameLoop.run(GameLoop.java:24)
at java.lang.Thread.run(Unknown Source)
The code I have in Game.java is:
我在 Game.java 中的代码是:
package game;
import java.applet.*;
import java.awt.*;
public class Game extends GameLoop{
public void init(){
setSize(864,480);
Thread th = new Thread(this);
th.start();
offscreen = createImage(864,480);
d = offscreen.getGraphics();
addKeyListener(this);
}
public void paint(Graphics g){
d.clearRect(0, 0, 864, 480);
d.drawImage(background, 0, 0, this);
d.drawRect(x, y, 20, 20);
g.drawImage(offscreen, 0, 0, this);
}
public void update(Graphics g){
paint(g);
}
}
And here is my GameLoop.java:
这是我的 GameLoop.java:
package game;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class GameLoop extends Applet implements Runnable, KeyListener{
public int x, y;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right;
public BufferedImage background;
public void run(){
x = 100;
y = 100;
try {
background = ImageIO.read(new File("background.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
while(true){
x = 100;
y = 100;
while(true){
if (left == true){
x-=4;
}
if (right == true){
x+=4;
}
if (up == true){
y-=4;
}
if (down == true){
y+=4;
}
if ( x <= 0 ){
x = 0;
}
if ( y <= 0 ){
y = 0;
}
if ( x >= 843 ){
x = 843;
}
if ( y >= 460 ){
y = 459;
}
repaint();
try{
Thread.sleep(20);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
//@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 37){
left = true;
}
if(e.getKeyCode() == 38){
up = true;
}
if(e.getKeyCode() == 39){
right = true;
}
if(e.getKeyCode() == 40){
down = true;
}
}
//@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == 37){
left = false;
}
if(e.getKeyCode() == 38){
up = false;
}
if(e.getKeyCode() == 39){
right = false;
}
if(e.getKeyCode() == 40){
down = false;
}
}
//@Override
public void keyTyped(KeyEvent e) {
}
}
Sorry about the editing I can't seem to get it all in the ``, and I will also fix the messy code, but do you guys have any ideas what is causing this error, there is a file in the src dir called background.png, it is very basic and made in MS paint, if that helps.
抱歉编辑我似乎无法在``中全部完成,我也会修复凌乱的代码,但是你们知道导致此错误的原因吗,src目录中有一个名为背景的文件.png,如果有帮助的话,它是非常基本的并且是用 MS 绘制的。
Thanks.
谢谢。
回答by Andrew Thompson
There are two places a simple, sand-boxed applet can obtain images.
一个简单的沙盒小程序可以在两个地方获取图像。
Where
在哪里
- A loose file on the same server the applet was supplied from. E.G. This might be used for a sand-boxed 'image slideshow' where the image names are supplied in applet parameters.
- A Jar on the run-time class-path of the applet. Best for resources which would not typically change (barring localized images, where it becomes more complicated). E.G. This might be used for button/menu icons, or BG images.
- 提供小程序的同一服务器上的松散文件。EG 这可能用于沙盒“图像幻灯片”,其中图像名称在小程序参数中提供。
- 小程序运行时类路径上的 Jar。最适合通常不会改变的资源(除非本地化的图像变得更加复杂)。EG 这可能用于按钮/菜单图标或 BG 图像。
"background.png"
strongly indicates the 2nd scenario - 'part of the app. itself'.
"background.png"
强烈表示第二种情况 - '应用程序的一部分。本身'。
How to find
怎么找
Both types of resources should identified by URL
(do not try to establish a File
as it will fail when the applet is deployed).
两种类型的资源都应该由URL
(不要尝试建立 ,File
因为部署小程序时它会失败)。
The way to obtain an URL
for the 2nd case is something along the lines of:
URL
为第二种情况获得 an 的方法是:
URL urlToBG = this.getClass().getResource("/path/to/the/background.png");
..where /path/to/the/
might simply be /resources/
or /images/
. It is the path within a Jar on the classpath, where the image can be found.
..where/path/to/the/
可能只是/resources/
或/images/
. 它是类路径上 Jar 中的路径,可以在其中找到图像。
How to load
如何加载
Most methods that will load a File
are overloaded to accept an URL
. This notably applies to ImageIO.read(URL)
.
大多数将加载 a 的方法File
都被重载以接受 an URL
。这尤其适用于ImageIO.read(URL)
.
While the Applet
class has inbuilt methods to load images, I recommend sticking with ImageIO
since it provides more comprehensive feed-back on failure.
虽然Applet
该类具有加载图像的内置方法,但我建议坚持使用,ImageIO
因为它提供了更全面的失败反馈。
Further tips
更多提示
Tip 1
提示 1
Thread.sleep(20);
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n)
implement a Swing Timer
for repeating tasks or a SwingWorker
for long running tasks. See Concurrency in Swingfor more details.
不要阻塞 EDT(事件调度线程) - 发生这种情况时 GUI 将“冻结”。而不是调用为重复任务或长时间运行的任务Thread.sleep(n)
实现 Swing 。有关更多详细信息,请参阅Swing 中的并发。Timer
SwingWorker
Tip 2
提示 2
It is the third millennium, time to start using Swing instead of AWT. That would mean extending JApplet
instead of Applet
. Then you might shift the logic of painting into a JPanel
that is double-buffered by default, and could be used in either the applet or a frame (or a window or a dialog..).
现在是第三个千年,是时候开始使用 Swing 而不是 AWT。那将意味着扩展JApplet
而不是Applet
. 然后,您可以将绘画逻辑转换为JPanel
默认情况下双缓冲的逻辑,并且可以在小程序或框架(或窗口或对话框..)中使用。
Tip 3
提示 3
setSize(864,480);
The size of an applet is set in HTML, and the applet should accept whatever size it is assigned and work within that. Taking that into account, statements like:
小程序的大小在 HTML 中设置,小程序应该接受它分配的任何大小并在其中工作。考虑到这一点,声明如下:
d.clearRect(0, 0, 864, 480);
..should read more like:
..应该更像是:
d.clearRect(0, 0, getWidth(), getHeight());
回答by konsnos
@Patricia Shanahan Your comment actually helped me to solve the same problem.
@Patricia Shanahan 您的评论实际上帮助我解决了同样的问题。
I've used that code:
我用过那个代码:
File here = new File(".");
try {
System.out.println(here.getCanonicalPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and from there you can figure out the correct path to use.
从那里你可以找出正确的使用路径。