实现从浏览器下载服务器文件到指定文件夹

步骤大概分为几步:

  1. 读取并在前端显示服务器的文件
  2. 从前端发出请求下载文件
  3. 到后端获取下载文件的流并保存
    demo是从网上找并且修改的,项目日期比较急。改的有点粗糙,有几个点可以优化下

下面逐步讲解
1、首先应该发送请求到后端读取本地文件,无非就是ajax略
2、后端接收请求并扫秒目标目录里及其子目录文件,改的比较丑陋。大致思想是遇见文件插入,再读取遇见里面的文件,这么一层一层下去。

    public static List<FileInfo> getLandBaseFileList(String path) {
        /*"/projects/smart_gateway/Customer/"
         * */

        List<FileInfo> fileInfos = new ArrayList<>();
        List<FileInfo> fileInfos2 = new ArrayList<>();
        File baseFile = new File(path);
        File[] files = baseFile.listFiles();
        //TODO  如果是文件在这里插入,如果是文件夹执行后面的操作
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()){
                FileInfo cursor = new FileInfo();
                cursor.setPath(files[i].getPath());
                cursor.setFileName(files[i].getName());
                num=num+1;
                cursor.setNum(num);
                fileInfos.add(cursor);
            }
            else {
                String path1=files[i].getPath();
                fileInfos2= FileService.getLandBaseFileList2(path1,fileInfos);
                fileInfos=fileInfos2;
            }
        }
        System.out.println(fileInfos);
        num=0;
        return fileInfos;
    }
    public static List<FileInfo> getLandBaseFileList2(String path,List<FileInfo> fileInfos) {
        /*"/projects/smart_gateway/Customer/"
    //TODO 递归获得所有文件夹
         * */
        List<FileInfo> fileInfos2 = new ArrayList<>();
        File baseFile = new File(path);
        File[] files = baseFile.listFiles();
        if (files!=null)
            for (int i = 0; i < files.length; i++) {
                if (files[i].isFile()){
                    FileInfo cursor = new FileInfo();
                    cursor.setPath(files[i].getPath());
                    cursor.setFileName(files[i].getName());
                    num=num+1;
                    cursor.setNum(num);
                    fileInfos.add(cursor);
                }
                else {
                    String path1=files[i].getPath();
                    fileInfos2= FileService.getLandBaseFileList2(path1,fileInfos);
                    fileInfos=fileInfos2;
                }
            }
        System.out.println(fileInfos);
        return fileInfos;
    }

3、前端展示

function setTbody (arr) {
	var html = '';
	for (var i = 0; i < arr.length; i++) {
		var item = arr[i];
		var path =item.path;
		/*  download    item.path*/
		var str=path.split("\\");
		var savpath="";
		for(var j=2 ;j<str.length; j++)
		{
			savpath=savpath+"\\"+str[j];
		}
	html += '<tr><td>' + item.num + '</td><td>' + savpath + '</td><td>' + '<a href="/download?downFilePath=' + encodeURI(path)  + '"' + '>' + '下载 </a>' + '</td></tr>';
	}
	$('.tbody').append(html);
}

这里没有后端分页,以后文件量大的话需要修改一下
4、前端发送请求到后端下载
ajax略,无非就是拿到一个文件名

        // 判断文件是否存在
        File file = new File(filePath);
        log.info("DOWNLOAD PATH:" + filePath);
        if (!file.exists() || file.isDirectory()) {
            log.info("FILE DOES NOT EXIST!");
            return "failure";
        }
        // 自定义文件名
        String[] split = filePath.split("/");
        String filename = split[split.length - 1];
        System.out.println(filename);
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        InputStream in = null;
        BufferedInputStream bis = null;
        OutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            in = new FileInputStream(filePath);
            bis = new BufferedInputStream(in);
            byte[] data = new byte[1024];
            int bytes = 0;
            out = response.getOutputStream();
            bos = new BufferedOutputStream(out);
            while ((bytes = bis.read(data, 0, data.length)) != -1) {
                bos.write(data, 0, bytes);
            }
            bos.flush();
        } catch (Exception e) {
            log.error("THE REQUEST FAILED:" + e.getMessage(), e);
            return "failure";
        } finally {
            try {
                if (bos != null) {
                    bos.close();
                }
                if (out != null) {
                    out.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     return "success";
    }

然后就完成了,发现是直接下载到指定的文件名那里,相对路径会是浏览器下载的路径+指定文件名,绝对路径就是绝对路径那。于是我想着能不能弹出一个对话框那样指定下载路径,一开始想着改改请求头就行了。找了半天没找到,后来一想请求头也确实做不到啊 - -,通过请求头直能下载到指定的路径(后端设置请求头时完成),要想指定路径还是得通过js,于是想到了file-input标签,读取本地路径就可以了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript 本身是不能将文件保存到指定文件夹中的,这是由于浏览器的安全机制所限制的。如果 JavaScript 能够随意地在用户的计算机上创建和操作文件,那么就会带来很大的安全风险。 不过,你可以使用一些技术来实现类似的功能。例如,可以使用服务器端的脚本语言(如 PHP、Node.js 等)来接收前端上传的文件,并将其保存到指定文件夹中。具体的实现方式,可以参考以下步骤: 1. 在前端页面中,使用 `input` 元素的 `type="file"` 属性创建一个文件上传框,让用户选择要上传的文件。 ```html <input type="file" id="fileInput"> ``` 2. 使用 JavaScript 获取上传框中选择的文件,并将其发送到服务器端。 ```javascript var fileInput = document.getElementById('fileInput'); var file = fileInput.files[0]; var xhr = new XMLHttpRequest(); xhr.open('POST', '/upload', true); var formData = new FormData(); formData.append('file', file); xhr.send(formData); ``` 3. 在服务器端接收上传的文件,并将其保存到指定文件夹中。 以 Node.js 为例,可以使用 `fs` 模块中的 `createWriteStream` 方法来创建一个可写流,将上传的文件写入到指定文件夹中。 ```javascript const fs = require('fs'); const path = require('path'); const express = require('express'); const app = express(); app.post('/upload', (req, res) => { const file = req.files.file; const filePath = path.join(__dirname, 'uploads', file.name); const writeStream = fs.createWriteStream(filePath); file.pipe(writeStream); writeStream.on('finish', () => { res.send('上传成功!'); }); }); app.listen(3000, () => { console.log('服务器启动成功!'); }); ``` 在这个例子中,我们将上传的文件保存到了 `uploads` 文件夹中。当文件上传完成后,服务器会返回一个成功的响应。需要注意的是,这里使用了 `pipe` 方法将文件的可读流和可写流连接起来,实现文件的写入操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值