关于项目中读取文件的探讨
2016-09-24 16:28
246 查看
知识点来自:
1.javase中的类加载路径
2.java.io中的基本api类
前言:
最近负责一个代码生成器的项目,还要做成一个eclipse插件的形式,后期还要做成可视化的方式。本身项目所要求的技术点不难,需要用到大量的文件读写,文件复制,已经文件所在位置的查找,读写以及复制比较好说,前提就是查找文件所在位置这点,故此有了此篇文章。
先来说一个概念:
URL:是网络中存在的一个资源文件,表示统一资源定位符号(uniform resource locator URL),表示toString的形式一般是:file:/D:/Day1.java或者jar:/D:/Day1.java,还有或者是其他的,例如笔者所做的项目中URL表示形式:bundleresource://709.fwk15218962:1/META-INF/MANIFEST.MF
File:表示的是一个文件,可以是目录,也可以是文件夹,表示toString的形式是:D:\Day1.java
以上2点很概念重要,对于子个项目进行集成时候。
进入正题:
读取项目中的文件(位置):
maven项目中的目录结构以及真实发布后的结构如下:
![](https://img-blog.csdn.net/20160924105606265?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
我们要读的是红线画圈的所表示的文件,实际打包后要读取的是target中的打包中文件所在的位置,推荐方式使用java的class所在方式进行读取。
使用类加载的方式读取文件的好处是能读取到classes中该类所在的位置,在在同级,上级,下级目录或者文件就简单容易很多。
细节如下:
1.getResource()
打印结果:
不加/和加/的区别:前者查找出类所在的绝对路径,后者加/是查找classes下的路径,/com则是查找classes下的com路径,若没有则会抛出空指针异常。
注意,在maven项目汇总的test目录下进行测试时候会发现,resource1的打印结果会是file:/D:/Users/eclipse-git/File/target/test-classes/,但是项目的真实环境不会出现,没人会把test下的文件拿出来使用。
2.getClassLoader
与上面类似。只不过相反,不做解释
对应的读取文件位置就简单多了:
打印结果为true
这种方式真是是一劳永逸吗?
--------------------------------------------------------------------------------jar篇幅-------------------------------------------------------------------------------------------------------------------------------------
尝试着把你那个项目使用maven依赖,供其他子项目进行使用,你发现原来读写那个文件是好使的变成不好使不?依赖的pom文件如下:
![](https://img-blog.csdn.net/20160924170444205?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
之前File项目中有一个MyFile测试方法内容如下:
打印结果:
一个是类路径下放的一个文件,一个是resource下存放的一个文件,都有。此时在新的项目TestMaven下面执行该方法,结果如下:
可以看到放在类路径下的文件找到了打印为True,而在resource下的文件确找不到打印却为了fasle。
分析原因,不难找出, MyFile.class.getResource("/")获取resources根路径时候找的是本项目的,此项目若没有则不会在其他依赖中的项目进行查找。
问题?若其他项目放在了resources下的文件如何查找呢?
带着这个问题,试着将之前的那个文件打包成jar,供另一个maven项目使用。此时的项目目录结构如下:
![](https://img-blog.csdn.net/20160924172114432?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
同样的MyFile测试方法方法,执行结果如何呢?
分析结果:都为false文件查找不存在,第二个还是查找本项目中的resources下的文件所有查找不到,但是第一个打印的是什么?jar,回头看看打印出jar这个函数:
URL resource = MyFile.class.getResource("/com/lgy/file/");
System.out.println(resource.getProtocol());
没错就是URL中的protocol,URL中的协议类型说明了此资源定位符所在的协议类型是什么,此时打印出来的jar恰巧说明了文件在jar中。若要读取该下的文件如何读取呢?
方式一:
类加载起中有一种加载方式可以获取到jar下的文件,以流的方式:
此时并可读到在类路径下的ccc.txt下的内容文件。
方式二:
如果文件的协议是jar,则用解析jar的方式进行:
最后关于URL的一个问题,笔者在制作eclipse plugin的时候遇到读取file是的协议是:bundleresource,解决思路是:
使用eclipse中提供的api转换为新的URL,此时的URL是的协议类型是jar,在解析的话就容易许多。
完结,总结不易,但是成长确实很大。
1.javase中的类加载路径
2.java.io中的基本api类
前言:
最近负责一个代码生成器的项目,还要做成一个eclipse插件的形式,后期还要做成可视化的方式。本身项目所要求的技术点不难,需要用到大量的文件读写,文件复制,已经文件所在位置的查找,读写以及复制比较好说,前提就是查找文件所在位置这点,故此有了此篇文章。
先来说一个概念:
URL:是网络中存在的一个资源文件,表示统一资源定位符号(uniform resource locator URL),表示toString的形式一般是:file:/D:/Day1.java或者jar:/D:/Day1.java,还有或者是其他的,例如笔者所做的项目中URL表示形式:bundleresource://709.fwk15218962:1/META-INF/MANIFEST.MF
File:表示的是一个文件,可以是目录,也可以是文件夹,表示toString的形式是:D:\Day1.java
以上2点很概念重要,对于子个项目进行集成时候。
进入正题:
读取项目中的文件(位置):
maven项目中的目录结构以及真实发布后的结构如下:
我们要读的是红线画圈的所表示的文件,实际打包后要读取的是target中的打包中文件所在的位置,推荐方式使用java的class所在方式进行读取。
使用类加载的方式读取文件的好处是能读取到classes中该类所在的位置,在在同级,上级,下级目录或者文件就简单容易很多。
细节如下:
1.getResource()
URL resource = MyFile.class.getResource(""); URL resource1 = MyFile.class.getResource("/");
打印结果:
file file:/D:/Users/eclipse-git/File/target/classes/com/lgy/file/ --------- d5c7 ----------- file file:/D:/Users/eclipse-git/File/target/classes/说明:
不加/和加/的区别:前者查找出类所在的绝对路径,后者加/是查找classes下的路径,/com则是查找classes下的com路径,若没有则会抛出空指针异常。
注意,在maven项目汇总的test目录下进行测试时候会发现,resource1的打印结果会是file:/D:/Users/eclipse-git/File/target/test-classes/,但是项目的真实环境不会出现,没人会把test下的文件拿出来使用。
2.getClassLoader
与上面类似。只不过相反,不做解释
对应的读取文件位置就简单多了:
URL resource = MyFile.class.getResource("/"); String path = resource.getPath(); System.out.println(path); File f = new File(path+ "bbb.txt") ; System.out.println(f.exists());
打印结果为true
这种方式真是是一劳永逸吗?
--------------------------------------------------------------------------------jar篇幅-------------------------------------------------------------------------------------------------------------------------------------
尝试着把你那个项目使用maven依赖,供其他子项目进行使用,你发现原来读写那个文件是好使的变成不好使不?依赖的pom文件如下:
<dependency> <groupId>com.lgy</groupId> <artifactId>File</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
之前File项目中有一个MyFile测试方法内容如下:
package com.lgy.file; import java.io.File; import java.net.URL; public class MyFile { public static void main(String[] args) { MyFile.test(); } public static void test() { //测试com/lgy/file 中的ccc.txt文件 URL resource = MyFile.class.getResource("/com/lgy/file/"); String path = resource.getPath(); System.out.println(resource.getProtocol()); System.out.println(path); File f = new File(path+ "ccc.txt") ; System.out.println(f.exists()); System.out.println("**************************"); //测试resources中的文件 URL resource1 = MyFile.class.getResource("/"); String path1 = resource1.getPath(); System.out.println(resource1.getProtocol()); System.out.println(path1); File f1 = new File(path1+ "aaa.txt") ; System.out.println(f1.exists()); } }
打印结果:
file /D:/Users/eclipse-git/File/target/classes/com/lgy/file/ true ************************** file /D:/Users/eclipse-git/File/target/classes/ true
一个是类路径下放的一个文件,一个是resource下存放的一个文件,都有。此时在新的项目TestMaven下面执行该方法,结果如下:
file /D:/Users/eclipse-git/File/target/classes/com/lgy/file/ true ************************** file /D:/Users/eclipse-git/TestMaven/target/classes/ false
可以看到放在类路径下的文件找到了打印为True,而在resource下的文件确找不到打印却为了fasle。
分析原因,不难找出, MyFile.class.getResource("/")获取resources根路径时候找的是本项目的,此项目若没有则不会在其他依赖中的项目进行查找。
问题?若其他项目放在了resources下的文件如何查找呢?
带着这个问题,试着将之前的那个文件打包成jar,供另一个maven项目使用。此时的项目目录结构如下:
同样的MyFile测试方法方法,执行结果如何呢?
jar file:/D:/Users/eclipse-git/File/target/File.jar!/com/lgy/file/ false ************************** file /D:/Users/eclipse-git/TestMaven/target/classes/ false
分析结果:都为false文件查找不存在,第二个还是查找本项目中的resources下的文件所有查找不到,但是第一个打印的是什么?jar,回头看看打印出jar这个函数:
URL resource = MyFile.class.getResource("/com/lgy/file/");
System.out.println(resource.getProtocol());
没错就是URL中的protocol,URL中的协议类型说明了此资源定位符所在的协议类型是什么,此时打印出来的jar恰巧说明了文件在jar中。若要读取该下的文件如何读取呢?
方式一:
类加载起中有一种加载方式可以获取到jar下的文件,以流的方式:
InputStream in = Test.class.getResourceAsStream("/com/lgy/file/ccc.txt");
此时并可读到在类路径下的ccc.txt下的内容文件。
方式二:
如果文件的协议是jar,则用解析jar的方式进行:
if (url.getProtocol().equalsIgnoreCase("jar")) { String path = MyFile.class.getProtectionDomain().getCodeSource().getLocation().getPath(); try { JarFile jf = new JarFile(path); Enumeration<JarEntry> e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = e.nextElement(); //获取jar中文件的名称 if (je.getName().startsWith("com/lgy/file/ccc.txt")) { System.out.println(je.getName()); System.out.println(je.isDirectory()); System.out.println(changeInpstream2String(jf.getInputStream(je))); } } jf.close(); } catch (IOException e) { e.printStackTrace(); } }
最后关于URL的一个问题,笔者在制作eclipse plugin的时候遇到读取file是的协议是:bundleresource,解决思路是:
package com.gsafety.cloudframework.eclipseurl; import java.io.IOException; import java.net.URL; import org.eclipse.core.runtime.FileLocator; public class EclipseLocator implements Locator { public URL resolve(URL url) { try { return FileLocator.resolve(url); } catch (IOException e) { e.printStackTrace(); } return url; } }
使用eclipse中提供的api转换为新的URL,此时的URL是的协议类型是jar,在解析的话就容易许多。
完结,总结不易,但是成长确实很大。
相关文章推荐
- 关于 Silverlight 项目文件 无法读取的问题
- 移动项目开发笔记(.net下关于上传文件解决方案比较和探讨)
- 关于一个项目中全局配置文件读取的注意事项
- qt中关于如何读取配置文件学习 (vs2008+qt+mysql项目)
- 关于怎么读取Maven项目resource目录下面的文件
- 关于IntelliJ IDEA创建项目无法读取配置文件
- 移动项目开发笔记(.net下关于上传文件解决方案比较和探讨)
- 在VS.NET内使用“从源代码管理打开”时出现无法读取项目文件的错误
- 今天解决了两个关于.NET读取EXCEL文件的问题,记下来,很有用!
- 今天解决了两个关于.NET读取EXCEL文件的问题,记下来,很有用!
- 关于读取txt文件的分段问题
- 把项目中的xml文件的生成操作改为“嵌入的资源”,我在这个项目中怎么读取xml文件里的内容?
- [导入]在 Visual Studio .NET IDE 内使用“从源代码管理打开”时出现无法读取项目文件的错误
- 关于如何在BizTalk中为项目创建单独的配置文件[翻译]
- 关于Winform中资源文件的读取
- asp.net关于文件在数据库的存入和读取
- 关于软件实施项目管理的探讨
- [导入]在 Visual Studio .NET IDE 内使用“从源代码管理打开”时出现无法读取项目文件的错误
- 关于文件保存到数据库及其读取的方法
- 关于VS.NET 2005中文版项目模版文件丢失的解决方法,如WWF