前排提醒:本问题的解答在“错误产生原因”中,可以直接跳转查看
目录
项目场景和问题描述:
最近我写了一个需要用到图片的Java项目,由于用到swing,和之前的另一个项目类似,故而将之前的项目复制了一份,在它的基础上进行改写。写好并运行无误后,我新建了一个项目,将图包和源代码原封不动复制了过去,结果新项目图片无法正常显示。
解决过程:
①一开始我怀疑是源代码的问题,虽然众所周知.java文件是文本文件,但是我抱着试一试的心态在新项目里新建类,再把对应类复制过去,希望能够解决。结果:失败,排除源文件错误;
②后来我怀疑是lib包版本不一样导致的错误(之前的项目是3.0.7,新建的项目自动是从网上下载的4.0.0),于是我将新建项目的lib包换成之前项目的lib包。结果:失败,排除lib包版本导致的错误;
③之后我怀疑新项目出现未知问题导致图片正常读取但无法显示,于是我将图片路径从相对路径改为绝对路径。结果:正常显示图片,排除项目显示图片错误;
④怀疑路径对应字符串有误,将//改为/、\\、\。结果:失败,且之前项目使用//可以正常读取。
⑤怀疑相对路径有误,查阅资料后发现无误,且之前项目和之后新项目源代码一模一样但一个可以读取一个不能读取也说明了源代码无罪。
⑥(此时已非常接近真相)怀疑新项目不能读取和src文件夹并列的img文件夹,于是将路径"..//img//RoutePage//RoutePage.png";改为".//img//RoutePage//RoutePage.png";,img文件从src文件上一级移到src文件内。结果:失败,于是找到老师交流解决。
解决方法:
新项目源文件中图片读取路径改为".//img//RoutePage//RoutePage.png",img文件夹移到src文件夹上一级文件夹内。
错误产生原因:
Java程序读取图片等信息时,程序运行的位置由相应标识文件确定,而并非简单按照Java源代码所在文件夹的路径读取。
对于不同的IDE,Java文件在编译时会产生不同的标识文件,IDEA是.iml文件,而Eclipse是.project文件,程序经由IDE编译运行的地址则由标识文件确定。
在上述例子中我第一个项目的.iml文件在src文件夹中,而第二个项目的.iml文件在src文件夹的上一级文件夹中,故而对于相同的源代码和图片路径".//img//RoutePage//RoutePage.png",第一个项目的img文件夹需要放在src文件夹中,而第二个项目需要将img文件夹放在src文件夹上一级文件夹中。
反思:
学习C语言的惯性思维让我误以为程序源文件的位置既是程序运行位置,这个结论对于C语言适用,但对于Java等语言就不再适用了,以后需要注意。
IDEA产生的.iml文件的一些特点:
①一个项目中第一个运行的mail()方法会在src文件夹的上一级文件夹生成以这个main所在类名为名字的.iml文件,无论这个类和main方法后续是否还存在,这个.iml文件名都不会变;
②有些项目除了会在src文件夹上一级文件夹生成.iml文件外,还会在src文件中生成第二个.iml文件,而另外一部分则不会。对于在src文件夹里生成了.iml文件的项目来说,它运行的位置就在src文件夹,src文件夹的上一级文件夹中的.iml文件被弃用,删除后不影响程序运行;而对于只在src文件夹的上一级文件夹中生成了.iml文件的项目,该项目的运行位置在src文件夹的上一级文件夹中。
IDEA产生的.iml文件的一个问题:
参考特点②,为什么所有项目在src文件夹的上一级文件夹生成.iml文件后,部分项目会在src文件夹中再生成一个.iml文件,而另一部分则部分不会?我暂时没有试出规律,也暂时没有查到相应资料,需要继续找原因。