spring boot 下載單個文件與文件夾打包為zip下載


支持文件單個下載,也支持文件夾打包下載。

package com.xxx.logs.console.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.LinkedList;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping("/logs/system")
public class LogsSystemController extends BaseController {


    @GetMapping("/download")
    public void download(HttpServletResponse response, @RequestParam("path") String path) throws Exception {
        // 轉為path
        Path folderPath = Paths.get(path);
        // 響應為二進制數據流
        response.setContentType("application/octet-stream");
        if (!Files.isDirectory(folderPath)) { // 文件下載
            File file = new File(path);
            if (!file.exists()) {
                LOGGER.error("file not exists: " + path);
                throw new IOException("file not exists: " + path);
            }
            try (InputStream input = new FileInputStream(file);
                 OutputStream output = response.getOutputStream()) {
                // 寫入數據
                int len;
                // 設置10kb緩沖區
                byte[] buffer = new byte[1024 * 10];
                // 文件設置,附件的形式打開
                response.setHeader("content-disposition", "attachment; filename=" + file.getName());
                while ((len = input.read(buffer)) > 0) {
                    output.write(buffer, 0, len);
                }
                output.flush();
            } catch (IOException e) {
                LOGGER.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
        } else { // 文件夾下載
            // 文件設置,附件形式打開
            response.setHeader("content-disposition", "attachment; filename=" + new String((folderPath.getFileName().toString() + ".zip").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
                // 文件路徑/ID
                LinkedList<String> filePath = new LinkedList<>();

                Files.walkFileTree(folderPath, new FileVisitor<Path>() {

                    @Override
                    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                        // 開始遍歷目錄
                        if (!dir.equals(folderPath)) {
                            filePath.addLast(dir.getFileName().toString());
                            // 寫入目錄
                            ZipEntry zipEntry = new ZipEntry(filePath.stream().collect(Collectors.joining("/", "", "/")));
                            try {
                                zipOutputStream.putNextEntry(zipEntry);
                                zipOutputStream.flush();
                            } catch (IOException e) {
                                LOGGER.error(e.getMessage(), e);
                                throw new RuntimeException(e);
                            }
                        }
                        return FileVisitResult.CONTINUE;
                    }

                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                        // 開始遍歷文件
                        try (InputStream inputStream = Files.newInputStream(file)) {

                            // 創建一個壓縮項,指定名稱
                            String fileName = filePath.size() > 0
                                    ? filePath.stream().collect(Collectors.joining("/", "", "")) + "/" + file.getFileName().toString()
                                    : file.getFileName().toString();

                            ZipEntry zipEntry = new ZipEntry(fileName);
                            // 添加到壓縮流
                            zipOutputStream.putNextEntry(zipEntry);
                            // 寫入數據
                            int len;
                            // 設置10kb緩沖區
                            byte[] buffer = new byte[1024 * 10];
                            while ((len = inputStream.read(buffer)) > 0) {
                                zipOutputStream.write(buffer, 0, len);
                            }

                            zipOutputStream.flush();
                        } catch (IOException e) {
                            LOGGER.error(e.getMessage(), e);
                            throw new RuntimeException(e);
                        }
                        return FileVisitResult.CONTINUE;
                    }

                    @Override
                    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                        return FileVisitResult.CONTINUE;
                    }

                    @Override
                    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                        // 結束遍歷目錄
                        if (!filePath.isEmpty()) {
                            filePath.removeLast();
                        }
                        return FileVisitResult.CONTINUE;
                    }
                });
                zipOutputStream.closeEntry();
            } catch (IOException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }


}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM