文件上传真Hard

一、SpringMVC实现文件上传

1.1.项目结构

1.1.2 控制器方法

    @RequestMapping("/upload1.do")
    public ModelAndView upload1(@RequestParam("file1") MultipartFile f1) throws IOException {
        //获取文件名称
        String originalFilename = f1.getOriginalFilename();
        String destFilePath = String.format("D:\\Study\\techCode\\SpringMVC\\mvc05-multifile\\src\\main\\webapp\\upfile\\%s", originalFilename);
        File destFile = new File(destFilePath);
        //调用transferTo将上传的文件保存到指定的地址
        f1.transferTo(destFile);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/WEB-INF/view/result.jsp");
        modelAndView.addObject("msg", destFile.getAbsolutePath());
        return modelAndView;
    }

①一开始控制器方法里面的destFile 是绝对路径,可以在webapp下的upfile文件夹找到传入的文件

②我把destFile改为"src\\main\\webapp\\upfile\\%s"后,发现在upfile文件夹下找不到了,返回的msg为下面这个,他不会去找项目下的upfile文件夹,而是在tomcat安装目录下自己创建一个新的文件夹,我属实没想到

③然后我又去查阅资料,好家伙,资料没找到,又有难题来了,下面这个输出的path是什么呢,我以为是上下文路径,结果呵呵,你自己看,原来是到target目录下了,毕竟这是编译后的代码,getRealPath("/")主打的就是一个真实,按理来说这才是正确的方法

String path = request.getSession().getServletContext().getRealPath("/");
D:\Study\techCode\SpringMVC\mvc05-multifile\target\mvc05-multifile\

④我想着应该有可以访问上下文路径的方法吧,果不其然找到了

String contextPath = request.getSession().getServletContext().getContextPath();

⑤那么我们回到②中的问题,找了资料后发现没有什么有用的信息,然后我就去debug源码,看了半天,似乎是会去找路径,没找到的话就会自己在tomcat下创建,比如我改成xxx\\main\\webapp\\upfile\\%s,结果就在tomcat目录下创建了一个xxx文件夹

⑥如果我改成"\\src\\main\\webapp\\upfile\\%s",就会发现在D盘创建一个src文件夹,这里的\\应该代表的是D盘根路径,tmd真复杂

大家看除了写成绝对路径,还有没有能够获取到webapp目录的方法,请在评论区发表,万分感谢!!!

1.1.3 前端

<form method="post" action="upload1.do" enctype="multipart/form-data">
    文件:<input type="file" name="file1"><br/>
    <input type="submit" value="提交">
</form>

二、SpringBoot实现文件上传

2.1 项目结构

2.2 控制器方法

 @RequestMapping("/upload1.do")
    public String upload1(@RequestParam("file1") MultipartFile f1, HttpServletRequest request) throws IOException {
        String path = request.getSession().getServletContext().getRealPath("/file");
        System.out.println("打印path:" + path);
        File f = new File(path);
        //判断路径若不存在则创建
        if (!f.exists()) {
            f.mkdirs();
        }
        //获取当前时间用于给新文件命名
        Date date = new Date();
        //给出时间格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        //以此来作为新文件名的一部分
        String fileName = simpleDateFormat.format(date);
        /*获取原始文件名带扩展名*/
        String allName = f1.getOriginalFilename();
        System.out.println("原始文件名allName:" + allName);
        /*获取扩展名 例如.doc */
        String extName = allName.substring(allName.lastIndexOf("."));
        System.out.println("扩展名extName:" + extName);
        //将传过来的file
        f1.transferTo(new File(path + "/" + fileName + extName));
        return f.getAbsolutePath();
    }

①我就是想看看这里的路径输出和MVC有什么不同,结果又要我大跌眼镜

C:\Users\yzh\AppData\Local\Temp\tomcat-docbase.8100.6395956201871802635\file

为什么又到C盘下去了呢?

原因分析:transferTo()方法调用时,判断如果是相对路径,则使用temp目录为父目录,因此保存在tomcat的临时work目录

②接着我想着能不能像MVC那样输出到target目录下呢?->找资料->把上面的path改为下面两个之一:

String path=ClassUtils.getDefaultClassLoader().getResource("").getPath()+"static/upload";
String path = ResourceUtils.getURL("classpath:").getPath() + "static/upload";

然后你直接访问http://localhost:port/upload/xxxx.jpg就可以直接看到文件了,omg!!!

③那么我想上传到static目录下怎么办呢?也只能写绝对路径吗?请在评论区发表,万分感谢!!!

三、获取resources下文件的方法

下面这三种方法获取的路径都是

D:\Study\techCode\SpringBoot\Boot-09-UploadFile\target\classes\1.txt

3.1 使用ResourceLoader接口

String path = resourceLoader.getResource("classpath:1.txt").getFile().getPath();

3.2  使用ClassPathResource

String path = new ClassPathResource("1.txt").getPath();

3.3 使用ResourceUtils.getFile()方法

File file = ResourceUtils.getFile("classpath:1.txt");
String path = file.getPath();
String absolutePath = file.getAbsolutePath();
String canonicalPath = file.getCanonicalPath();

在 Linux 中,每个文件和目录都有一个 inode,该 inode 记录了文件或目录的元数据信息。同时,每个文件系统都有一个 inode 表,用于记录该文件系统中所有文件和目录的 inode 号码和状态。文件系统的 inode 表是有限的,因此系统中能够创建的文件和目录数是有限的。 为了限制系统中文件和目录的数量,Linux 提供了 soft 和 hard 两种文件数限制机制。soft 文件数限制是一个警告阈值,当系统中的文件数达到该阈值时,系统会开始发出警告;而 hard 文件数限制是一个严格的限制阈值,当系统中的文件数达到该阈值时,系统会拒绝创建新的文件和目录。 这两种文件数限制机制的使用区别如下: 1. soft 文件数限制可以超过 hard 文件数限制,但是超过后系统会开始发出警告; 2. 如果系统中的文件数达到了 soft 文件数限制,但是没有达到 hard 文件数限制,那么系统仍然可以创建新的文件和目录; 3. 如果系统中的文件数达到了 hard 文件数限制,那么系统会拒绝创建新的文件和目录,直到释放了一些 inode 资源。 在 Linux 中,可以通过 ulimit 命令来查看和修改文件数限制机制的设置。例如,要查看当前系统中的 soft 和 hard 文件数限制,可以使用以下命令: ``` ulimit -a ``` 要修改文件数限制机制的设置,可以使用以下命令: ``` ulimit -n <value> ``` 其中,value 表示新的文件数限制值。需要注意的是,这种修改方式仅在当前 shell 环境中生效,如果要永久生效,需要修改系统配置文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间邮递员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值