idea读取文件时的路径问题
先来看一段关于FileInputStream读取文件的代码
package cn.zw.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
byte[] bytes = new byte[1024];
int len = 0;
while((len=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
这里要读取的文件所在目录结构是与Test模块平级,如图:
运行结果如下:
程序正确读到了test.txt文件,难道说idea默认路径就是是在工程目录下吗?
为了准确性,我们多测试一个路径:
当test.txt在模块内部时:
代码修改:
fis = new FileInputStream("Test/test.txt");
路径修改:
运行结果:
依旧成功!
那我们是不是以后就直接把文件要读取或写入的文件直接放到工程目录下就可以了?简单直接。。。
对于这个想法,我们打开out–>production–>Test,查看我们最后的成果:
发现out–>production–>Test目录下只有cn/zw/test/Test.class,跟本没有test.txt文件。当我们不借助idea执行Test.class会报错吗?
果然不行!
由于test.txt并没有放进out–>production–>Test目录下,产生了FileNotFoundException
如果我们自己把test.txt放到out–>production–>Test目录下,
并把代码修改:
fis = new FileInputStream("test.txt");
可能你会有疑问,为什么要修改,test.txt是在Test目录下的啊!干嘛还要修改啊!我们如果不借助idea,关于路径其实非常简单,以类所在路径为默认路径,
我们的Test.class的全限定类名为cn.zw.test.Test,即默认路径为out–>production–>Test,那Test.txt的相对路径就是“test.txt”
运行代码:
idea:
通过命令:
虽然出现中文乱码,但我们还是成功了。(关于中文乱码可能是由于Test.txt我用的是UTF-8,而DOS命令窗口是其他的编码方式吧,试一试把Test.txt另存为ANSI)
那我们怎样才能使idea自动将test.txt放入我们的out–>production–>Test目录下呢,很简单,src目录就是idea要处理的目录,位于src下的都会处理放入我们的out–>production–>Test下。所以我们的要读取/写入的文件最好放入到src目录下。
心细的同学可能发现了一个问题,当我完成一个模块的时候,要将我的out–>production下的Test提交时会出现问题:我的Test.class里面的路径是“Test/src/test.txt”。而test.txt是在out–>production–>Test下,class文件中正确路径应该是“test.txt”,t提交后的class文件很难修改,我们只能在out–>production–>Test下创造一个适合路径来迎合class,既难看又麻烦。
这时我们可以用:
String path = Thread.currentThread().getContextClassLoader().getResource("test.txt").getPath();
fis = new FileInputStream(path);
注意这个方法的默认路径为src/ (这就很棒了),所以我这里的传的参数为“test.txt”,也就是说test.txt放在src目录下。
编译后Test.class里的路径为“test.txt”,而test.txt就在out–>production–>Test中,路径就对上了,不管是idea,还是dos命令,我们都可以不做任何修改正确执行了。
接下来我们来看一个有趣的案例,文件的写入,对于一些像我一样的java新手可以说是太残暴了,整整花了我2个小时。
现在我们向test.txt文件添加内容:
package cn.zw.test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
String path = Thread.currentThread().getContextClassLoader().getResource("test.txt").getPath();
fos = new FileOutputStream(path,true);
fos.write("进击的巨人!".getBytes());
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
成功了!打开src/test.txt看看:
怎么回事?我不是添加了吗?这个问题把我这个新手困扰死了。。。
其实我们最终要访问的文件都是在out–>production–>Test目录下的,
idea会把test.txt复制到out–>production–>Test目录下,我们真正操作的是副
本!!!打开out–>production–>Test–>test.txt
发现我们其实是成功写入了的。。。。
总结:
**idea默认路径是工程目录,比如你创建了一个空工程项目EmptyJava,里面有两个模块Test和Test2,Test下的src放有test.txt。
当你在Test模块中写一个java程序进行i/o操作时,可以这样写:
String path = Thread.currentThread().getContextClassLoader().getResource("test.txt").getPath();
fos = new FileOutputStream(path,true);
这样不仅idea正确运行,不借助idea也可以的。
其次当你对文件进行读写操作时,并不是对EmptyJava–>Test–>src–>test.txt进行操作,而是对EmptJava–>out–>production–>Test–>test.txt进行操作。。。。
毕竟idea会把产品都放到out–>production目录下。**