1,前端上传的文件对象file
@PostMapping("/file") public String upload(MultipartFile file) throws IOException { //直接使用文件对象接收前端文件,不需要使用@RequestBody注解 String originalFilename = file.getOriginalFilename(); //获取文件原始名称,比如上传文件名为aa.txt long size=file.getSize()/1024; //获取文件大小,单位kb file.getContentType(); //获取文件类型,比如图片就是imag/jpe try{ file.transferTo(new File(System.getProperty("user.dir")+"/AA/BB/aa.txt") ) //可以传入java自动的文件对象 //这个表示将file中的数据写入到BB目录中的aa.txt文件中, BB目录必须是已存在的,这样就表示将file中的数据写入并生成了aa.txt文件 }catch(IOException e){ System.out.println("路径为找到") } //这个是上传文件的时候最容器包的错 transferTo在英文中表示"转移到", 其实就相当于将当前文件对象中的数据转移到磁盘对象中去
发现一个错误:
当在transferTo的文件对象中使用相对路径的时候,
transferTo的内部会自动在这个相对路径前面添加一个临时文件路径:C:\Users\zzzzz\AppData\Local\Temp\tomcat.8888.3312050621851573603\work\Tomcat\localhost\ROOT
-
-
-
所以你一定要使用绝对路径,或者也可以使用System.getProperty("user.dir")来获取当前的工作路径, transferTo()内部是无法识别"./"和"/"的,当transferTo()发现你的file对象是一个相对路径的时候,就会自动给你添加一个临时路径拼接上去,但是transferTo()是可以识别System.getProperty()的
比如: file.transferTo(new File("./AA/BB") )是错误的
file.transferTo(new File("/AA/BB") )也是错误的
-
-
-
其核心根本原因是:
1) new File("./AA/BB").mkdirs() //他会在当前工作目录中生成AA/BB目录
而使用:file.TransferTo(new File("./AA/BB") )它所找到的目录是" 临时目录/./AA/BB",自然就报错了
-
-
-
2) new File("/AA/BB").mkdirs() //它会在当前根目录下生成AA/BB目录
而使用:file.TransferTo(new File("/AA/BB") )它所找的目录是" 临时目录/AA/BB"
这个自然也会报错
-
-
-
3) new File(System.getProperty("user.dir")+"/AA/BB").mkdirs() //这个是正确的,
file.transferTo( new File(System.getProperty("user.dir")+"/AA/BB") )能过识别到System.getProperty()为当前的工作目录, 最终组成了一个绝对路径
-
-
-
-
-
如果说我非要使用相对路径呢:
一般transferTo()有两种使用方法:
a) transferTo(new File(“/AA/BB") ); //传入File对象的时候,如果使用的是相对路径,就会自动拼接上一个临时路径,从而就会如上所示报错
-
-
b) transferTo(Paths.get("/AA/BB") ) //这个Path对象可以识别到"./"和”/",所以不会报错,
//它就完美的解决了方法(a)所存在的问题了
注意:file是指文件上传对象
我在打包成docker镜像之后,运行的时候,transferTo()所添加的临时路径就是当前容器的根目录
比如:在镜像容器中运行:
new File("/AA/BB") //就是在当前容器的根目录中生成/AA/BB目录
file.transferTo(new File("/AA/BB") ) //它所添加的临时路径就是容器的根目录,所以不会报错
2,java自带的文件对象file
File file=new File("/AA/BB") //这里的路径是"/AA/BB"
file.mkdirs(); //生成多级目录
file.mkdir(); //只会生成最后一级目录,如果上一级不存在则不生成
发现一个奇怪现象:
当前项目运行在D盘中的D:/桌面/SpringBoot2022
file对象路径为: "/AA/BB"
生成的具体位置: D:/AA/BB
路径为:"./AA/BB"
生成的具体位置: D:/桌面/SpringBoot2022/AA/BB, 也就是和项目的src目录是在同一级
-
感觉就是打点".", 则会将当前项目的路径自动拼接上去,也就是项目的工作目录拼接上去了
其实还有一个高级用法: System.getProperty("user.dir"), 这个也是自动获取项目的工作目录,结果为D:/桌面/SpringBoot2022, 但是还是感觉直接在创建的时候打点"."比较方便
没有打点".", 则会直接向项目所在的根目录"D:"给拼接上去
-
-
-
在后面我将java项目打包成jar包后,又会产生的现象:
路径为: "./AA/BB"
将jar包放在路径为D:/桌面/SS中的SS文件夹中,
结果生成的文件夹的具体位置: D:/桌面/SS/AA/BB, 它并不会将文件夹生成到项目的内部,而是会将目录生成到jar包所在的目录中
-
-
-
-
路径为:"AA/BB"
将jar包还是放在路径为D:/桌面/SS中的SS文件夹中,
生成的文件夹的路径为: D:/AA/BB,
如果将jar包放在A:/桌面/SS中,生成文件夹的路径就是: A:/AA/BB
-
-
-
-
-
-
总结: 以"/"开头的相对路径, 会直接将程序目录所在的根路径自动拼接上
以"./"开头的相对路径,则会将程序的工作目录自动拼接上,
其中:jar包运行的目录就是工作目录,在没有打包时,springboot的工作目录需要自己进行区分
3, 工作目录的含义
所谓的工作目录就是创建Maven项目的最外层的那个目录,怎么说呢
比如:创建了一个SpringBoot项目,路径为: D:/桌面/SpringBoot
那么这个D:/桌面/SpringBoot就是当前项目的工作目录
-
-
-
再比如: 你随便创建一个文件夹AA, 路径为: D:/桌面/AA
然后通过idea打开这个文件夹AA
然后在文件夹AA中新建文件夹BB
然后在文件夹BB中新建一个模块,在这个模块中编写SpringBoot项目,该模块名称为music
此时在SpringBoot项目中的java代码中创建目录: new File("./zz").mkdirs()
那么这个zz目录会生成在哪呢,
首先你要知道"./"表示工作目录, 而该SpringBoot的工作目录就是D:/桌面/AA
所以最终生成的zz目录路径就是"D:/桌面/AA/zz"
如下图所示,虽然该springboot项目是在musice-server目录中,
但是它的工作目录还是为:"D:/桌面/音乐播放器"
也就是说所谓的工作目录,就是idea打开的这个文件夹旁边所显示的路径就是工作目录路径
通过运行System.getProperty("user.dir")也能获取工作目录路径