问:老师,同样的代码,为何我将Java工程改造成Maven后,始终无法运行?

实现的功能:加载abc.txt文件,代码是写在了Demo类中。

开发工具是Idea。

1.以下是普通Java工程的目录结构。

Demo代码如下

public class Demo {public static void main(String[] args)throws Exception{InputStream input = new FileInputStream("src/a/abc.txt") ;System.out.println();}
}

此时,程序能够正常运行。

2.现在将Java工程,改造成基于Maven的形式。目录结构如下。

Demo代码如下。

public 

Java工程的classpath是src;Maven工程的classpath有一个是resources。我也做了相应修改。但为何,此时用Maven写的同样功能代码,始终报错如下。

FileNotFoundException: 

答:

(赶时间的,可以略过分析,直接看本文最后的结论和源码)

“路径问题”首先得思考一个问题:程序中使用的相对路径,是基于最终执行的字节码路径,还是源码的路径?(比如原文件是A.java,编译后的文件是A.class。那么A在加载abc.txt时,“相对路径”是以“A.java”为参照点,还是以“A.class”为参照点?。

上面这个问题,暂时放一放。先直接看一下造成你疑惑的根本原因:普通的Java工程和Maven等构件工具,对.class文件和静态资源的打包路径不同。

1.打开普通Java工程中 字节码目录,如下。

发现了什么?在普通Java工程中在编译及运行阶段,并不会处理静态资源(也就是会忽略abc.txt文件)。因此,要加载abc.txt,就得去它原来的位置,即在src源码目录下,如图所示。

所以,在使用普通Java工程时,就需要在src下面找abc.txt(因为字节码目录中的静态资源,会被忽略)。因此,加载路径是源码src中的路径,而不是字节码classes中的路径,如下。

new 

2.但Maven工程对静态资源的处理方式则不同。

我们知道,Maven会将字节码和静态资源 都打包在 target下,如图所示。

也就是说,maven会将Demo.class和abc.txt一同打包在 字节码(target/classes)目录下。但要注意:maven默认在读取路径时, 是基于字节码classes目录,而不是源码src目录,这与普通Java工程完全相反。【因为maven的一个原则:就是想让 最终的执行程序,与源码相互隔离,互不干扰】。所以,如果使用了maven,静态资源的相对路径获取方式,就和普通Java工程不一样了(不能再从src中读取静态资源,而要从classes中读取)。

讲到这里,有同学可能会问“看上图,可知abc.txt就在Demo.class的上一级。因此在Demo.class中使用../abc.txt不就行了?”。看起来好像可以,但实际也不行。

使用../abc.txt的意思是,从当前路径开始,寻找上一级目录。这里说的当前路径好像就是字节码路径中的Demo.class文件本身。但实际情况真的是吗?使用以下代码,查看一下当前路径到底是什么。

public 

运行结果:

D:githubJavaCoresrcJavaBook.

发现 ,程序在执行时当前路径是在src下,根本不是classes字节码。这又与Maven的原则相违背(Maven默认读取的路径是字节码classes目录,而不是源码src目录)。【这种特性是jvm底层决定的,我们无法改变】。

以上,有些绕,总结就是:

java程序在使用相对路径,加载静态资源时:

1.普通Java工程加载的是源文件src目录中的静态资源;

2.Maven工程加载的是字节码目录target/classes中的静态资源;

3.在编写源码时,程序中相对路径基于的“当前路径”是在源文件src目录下 ,不是在classes目录下。(也就是当前路径是基于A.java,而不是基于A.class)。

以上三条中,“1”和“3”是一致的,所以普通Java工程方式加载静态资源,没有什么,直接写相对路径就行;但“2”和“3”在读取路径时是矛盾的,因此Maven工程在加载静态资源时,就不能使用相对路径,而需要使用绝对路径。

但还要注意,绝对路径要以动态的方式获取,防止不同环境之间的差异。

最后,给出Maven方式,获取静态资源的代码。

public 

很“简单”一个问题,是不是还挺绕人的~

- 完 -

推荐阅读

答疑 | 高并发都要学哪些技术?

答疑 | 我是JAVA初级,有必要学架构设计吗?

Java小白到大神的心路历程(Java SE)

答疑 | 面试全对,却没offer?

答疑 | 背下这300字,面试就能加薪!

java读取src路径下的txt文件_Java程序使用Maven后无法运行?相关推荐

  1. Java 读取src目录下的json文件

    直接上代码,但是有个乱码的地方需要特殊转码一下. /*** 读取json文件,返回json串* @param fileName* @return*/private String readJsonFil ...

  2. vMix对C盘路径下video.txt文件访问被拒绝怎么办

    vMix对C盘路径下video.txt文件访问被拒绝怎么办 新云小编发现一个问题在安装成功后,软件打不开.弹窗蹦出vmix打开出video.txt访问被拒绝!这下小编无语了.还好新云小编聪明去找了下发 ...

  3. Python碎片化学习教程 @19. 在指定路径下创建.txt文件,并写入内容

    代码功能:在指定路径下创建.txt文件,并写入内容 代码如下: file = open("1.txt", "w", encoding="utf8&qu ...

  4. Java读取指定路径下的文件列表

    直接贴代码吧.不过这里要做一个简单的说明,对于这个程序,我们必须保证我们在F盘下有一个log_files的文件夹,因为在后面写入文件的时候,如果路径中的文件不存在,是程序可以自动为其添加,但如果没有了 ...

  5. 安卓加载asset中的json文件_Android中读取asset路径下本地json文件

    最近自己写个小demo,用到了assets文件里面的内容.猛的没想起来怎么使用.就记录下来 移动端开发中,和后台的交互方式不外乎json和xml,由于json的轻量级以及易用性,所以现在的交互协议基本 ...

  6. Lua__读取指定路径下的.Lua文件

    using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; usin ...

  7. java合并txt文件_Java程序将两个txt文件合并为第三个txt文件 - Break易站

    让给定的两个文件是file1.txt和file2.txt.我们的任务是将两个文件合并到第三个文件,例如file3.txt,但合并应该逐行进行.以下是交替合并的步骤. 为file3.txt创建Print ...

  8. 制作英文学习词典。编写程序制作英文学习词典,词典有3个基本功能:添加、查询和退出。程序读取源文件路径下的txt格式词典文件,若没有就创建一个(Python)

    以下路径可更换为你自己的路径,本程序采用Python语言大致实现了serach()查询函数和add()添加函数.细节有待完善,谢谢 def search():w=input("请输入要查询的 ...

  9. c打开指定路径文件_C++ 读取指定路径下所有的文件 (C++ get the list of files in a directory)...

    电脑配置:window10, 64位操作系统,基于x64的处理器,Microsoft Visual Studio Community 2019 Version 16.4.5 实现方法:使用 boost ...

最新文章

  1. JavaScript 方法传参
  2. java学习笔记11--集合总结
  3. ES6对象(2):面向对象与类
  4. T60 改LED 高压板连线方式。
  5. C++关键字(3)——static
  6. 如何使用Magoshare Data Recovery在mac上恢复找回删除的丢失文件?
  7. python 高阶函数之filter
  8. axure 坐标扩散效果
  9. 动态获取API函数地址
  10. (z)无杂散动态范围SFDR--影响通信机性能的因素
  11. (三)基于Phyphox的三线摆法测量物体转动惯量
  12. icom对讲机写频线定义_自制电台通用写频线(完整版).pdf
  13. excel多个工作表合并在一个表
  14. 软件测试面试题:智力题。
  15. 大屏制作 | 完成一个美观大屏到底多简单?四步完成
  16. Java实现word文档转换图片功能
  17. 怎么把视频压缩成表情包?如何把视频做成GIF动图
  18. win10注册MSCOMM32控件及简单使用
  19. 计算机页面偏黄怎么修改,电脑显示器偏黄怎么调
  20. @RequiredArgsConstructor 代替@AutoWired注解

热门文章

  1. Tomcat6.0启动startup.bat一闪而过
  2. swift添加下拉刷新_React Native自定义下拉刷新组件
  3. 重定向index.php,使用htaccess将all重定向到index.php
  4. rust建的怎么拆除_农民为什么建简易房?
  5. Javascript - Vue - webpack
  6. Android ViewPager2 真的香么?
  7. 聊聊storm TridentBoltExecutor的finishBatch方法
  8. Linux学习笔记6月1日任务
  9. C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密
  10. 利用ASP控制WEB打印代码方法集合