文件上传本地服务器

文件上传的本质就是将文件通过IO流复制到服务器。文件上传是先上传到临时目录,然后再从临时目录复制到磁盘,目的是防止用户在上传途中网路中断、刷新页面导致文件上传失败,从而磁盘中产生大量垃圾文件和正常文件混在一起,所以只有文件上传成功后,才会从临时文件复制到磁盘,之后系统会自动删除临时文件。

前端HTML

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<form action="/upload/file" id="touploadform" enctype="multipart/form-data" method="post">

    <input name="dir" value="bbs">
    <input id="file" name="file" onchange="toupload()" type="file" accept="image/*"/>
    <script>
        function toupload(){
            document.getElementById("touploadform").submit();
        }

        file.addEventListener('change', async e => {
            const file = e.target.files[0]
            const flag = await isImage(file)
            if (flag) {
                alert('上传格式通过!')
            } else {
                alert('请上传正确的格式!')
            }
        })
        // 判断是否为图片
        async function isImage(file) {
            return (await isGif(file)) || (await isPng(file)) || (await isJpg(file))
        }
        // 判断是否为 jpg 格式
        async function isJpg(file) {
            const res = await blobToString(file.slice(0, 3))
            return res === 'FF D8 FF'
        }
        // 判断是否为 png 格式
        async function isPng(file) {
            const res = await blobToString(file.slice(0, 4))
            return res === '89 50 4E 47'
        }
        // 判断是否为 gif 格式
        async function isGif(file) {
            const res = await blobToString(file.slice(0, 4))
            return res === '47 49 46 38'
        }
        // 将文件转为十六进制字符串
        async function blobToString(blob) {
            return new Promise(resolve => {
                const reader = new FileReader()
                reader.onload = function () {
                    const res = reader.result
                        .split('') // 将读取结果分割为数组
                        .map(v => v.charCodeAt()) // 转为 Unicode 编码
                        .map(v => v.toString(16).toUpperCase()) // 转为十六进制,再转大写
                        .map(v => v.padStart(2, '0')) // 个位数补0
                        .join(' ') // 转为字符串
                    resolve(res)
                }
                reader.readAsBinaryString(blob) // 将文件读取为二进制字符串
            })
        }
    </script>
<!--    <input type="submit" value="文件上传">-->
</form>
</body>
</html>

 controller层

package com.kuangstuday.controller;

import com.kuangstuday.service.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Controller
public class UploadController {


    @Autowired
    private UploadService uploadService;

    @PostMapping("/upload/file")
    @ResponseBody
    public Map<String,Object> upload(@RequestParam("file")MultipartFile multipartFile, HttpServletRequest request){
        if (multipartFile.isEmpty()){
            return null;
        }

        //1:获取用户指定的文件夹。问这个文件夹为什么要从页面上传递过来呐?
        //原因是:做隔离,不同业务,不同的文件夹放在不同的目录中
        String dir = request.getParameter("dir");
        return uploadService.uploadImg(multipartFile,dir);
    }
}

service层

package com.kuangstuday.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class UploadService {
    /**
     * multipartFile 这个对象是springmvc提供的文件上传接受的类
     * 它的底层自动会去和HttpServletRequest request 中的request.getInputStream()融合
     * 从而达到文件上传的效果,也就是告诉你一个道理:
     * 文件上传的原理是:request.getInputStream()
     * @param multipartFile
     * @param dir
     * @return
     */
    //从yml文件读取配置
    @Value("${file.uploadFolder}")
    private String uploadFolder;

    @Value("${file.staticPath}")
    private String staticPath;
    public Map<String,Object> uploadImg(MultipartFile multipartFile, String dir){
        try {
            String realfilename = multipartFile.getOriginalFilename();//上传的文件:aaa.jpg
            //2.截取文件名的后缀
            String imgSuffix = realfilename.substring(realfilename.lastIndexOf("."));//拿到: jpg
            //3.生成的唯一的文件名:能不能用中文? 不能,因为统一用英文名
            String newFileName = UUID.randomUUID().toString()+imgSuffix;//将aaa.jpg改写成:SD22424241-323432ms.jpg
            //4.日期目录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date());//日期目录:2022/11/08
            //5.指定文件上传的目录
            String servrepath= uploadFolder;
            File targetFile = new File("E://tmp/"+dir,datePath);//生成一个最终目录:E://temp/bbs/2021/10/37
            //如果文件夹不存在,则自动创建
            if (!targetFile.exists())targetFile.mkdirs();//如果目录不存在递归创建:E://temp/bbs/2021/10/37
            //6.指定文件上传以后的目录
            //文件上传到服务器最终为:E://temp/bbs/2021/10/37/SD22424241-323432ms.jpg
            File targetFileName = new File(targetFile,newFileName);
            //7.文件上传到指定目录
            multipartFile.transferTo(targetFileName);//将用户选择的aaa.jpg,上传到服务器E://temp/bbs/2021/10/37/SD22424241-323432ms.jpg

            Map<String,Object> map = new HashMap<>();
            map.put("url",staticPath+"/upimges/"+dir +"/"+ datePath +"/"+newFileName);
            map.put("size",multipartFile.getSize());
            map.put("ext",imgSuffix);
            map.put("filename",realfilename);
            map.put("rpath",dir+"/"+ datePath +"/"+newFileName);
            return map;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

application.yml文件

server:
  port: 8777


spring:
  freemarker:
    suffix: .html
    cache: false
  servlet:
    multipart:
      enabled: true
#      单个文件大小  默认1MB
      max-file-size: 1MB
#      设置总上传的文件大小
      max-request-size: 10MB
#      当文件达到多少时进行磁盘写入
      file-size-threshold: 20MB
#      设置临时目录
      location: E://data//temp

config层

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
    /**方法一:这个就是springboot中springMvc让程序开发者去配置文件上传的额外的静态资源服务的配置
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/uploadimg/**").addResourceLocations("file:E://tmp//");
    }
     *registry.addResourceHandler("访问的路径").addResourceLocations("上传资源的路径");
     *这个时候你把aaa.png文件上传到了E://tmp下,那么,你可以通过:http://localhost:8777/uploadimg/aaa.png访问到图片
    */

    @Value("${file.staticPatternPath}")
    private String staticPatternPath;
    @Value("${file.uploadFolder}")
    private String uploadFolder;
    /**
     * 方法二
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(staticPatternPath).addResourceLocations("file:"+uploadFolder);
    }
}

application-dev.yml配置

# 本级配置
file:
  staticPatternPath: /upimges/**
  uploadFolder: E:/tmp/

application-prod.yml配置

#服务器配置
file:
  staticPatternPath: /upimges/**
  uploadFolder: /www/upload

application.yml配置激活dev

server:
  port: 8777


spring:
  freemarker:
    suffix: .html
    cache: false
  profiles:
    active: dev
  servlet:
    multipart:
      enabled: true
#      单个文件大小  默认1MB
      max-file-size: 1MB
#      设置总上传的文件大小
      max-request-size: 10MB
#      当文件达到多少时进行磁盘写入
      file-size-threshold: 20MB
#      设置临时目录
      location: E://data//temp

在浏览器访问http://localhost:8777/upimges/bbs/2022/11/09/2454a5bf-29e2-42b7-a7d6-8b37b0903668.png

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将文件从本地上传到Linux系统,可以使用以下方法: 1.使用scp命令:scp是一种安全的文件传输协议,可以在本地和远程系统之间传输文件。使用以下命令将文件从本地上传到Linux系统: scp /path/to/local/file username@remote:/path/to/remote/directory 其中,/path/to/local/file是本地文件的路径,username是Linux系统的用户名,remote是Linux系统的IP地址或主机名,/path/to/remote/directory是Linux系统上要上传文件的目录路径。 2.使用sftp命令:sftp是一种安全的文件传输协议,可以在本地和远程系统之间传输文件。使用以下命令将文件从本地上传到Linux系统: sftp username@remote put /path/to/local/file /path/to/remote/directory 其中,username是Linux系统的用户名,remote是Linux系统的IP地址或主机名,/path/to/local/file是本地文件的路径,/path/to/remote/directory是Linux系统上要上传文件的目录路径。 3.使用rsync命令:rsync是一种快速、灵活、安全的文件传输工具,可以在本地和远程系统之间同步文件。使用以下命令将文件从本地上传到Linux系统: rsync -avz /path/to/local/file username@remote:/path/to/remote/directory 其中,/path/to/local/file是本地文件的路径,username是Linux系统的用户名,remote是Linux系统的IP地址或主机名,/path/to/remote/directory是Linux系统上要上传文件的目录路径。-avz选项表示以归档模式同步文件,并压缩传输数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值