【java】文件操作汇总

java常见文件操作

上传下载

针对文件上传和下载,以下是基于 Spring Boot 的优化实现方案。采用流式传输避免内存溢出,包含异常处理和基础安全校验:

// FileController.java
@RestController
public class FileController {
    
    // 从配置文件中读取存储路径(application.yml/properties)
    @Value("${file.upload-dir}")
    private String uploadDir;

    // 上传文件
    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return ResponseEntity.badRequest().body("请选择要上传的文件");
            }

            // 安全校验文件名
            String fileName = StringUtils.cleanPath(file.getOriginalFilename());
            if (fileName.contains("..")) {
                return ResponseEntity.badRequest().body("文件名包含非法路径序列");
            }

            // 创建存储目录(如果不存在)
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 使用try-with-resources自动关闭资源
            try (InputStream inputStream = file.getInputStream()) {
                Path filePath = uploadPath.resolve(fileName);
                Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
            }

            return ResponseEntity.ok("文件上传成功: " + fileName);
        } catch (IOException e) {
            return ResponseEntity.internalServerError().body("上传失败: " + e.getMessage());
        }
    }

    // 下载文件
    @GetMapping("/download/{fileName:.+}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
        try {
            Path filePath = Paths.get(uploadDir).resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());

            if (!resource.exists()) {
                return ResponseEntity.notFound().build();
            }

            // 设置响应头
            String contentType = Files.probeContentType(filePath);
            if (contentType == null) {
                contentType = "application/octet-stream";
            }

            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, 
                            "attachment; filename=\"" + resource.getFilename() + "\"")
                    .body(resource);
        } catch (IOException e) {
            return ResponseEntity.internalServerError().build();
        }
    }
}

配置 application.yml:文件路径按照个人需求修改

file:
  upload-dir: /var/data/uploads  # Linux示例路径
  # 或者 Windows路径示例:C:/app_uploads

pom依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
</dependencies>

优化点说明:

安全防护:

使用 StringUtils.cleanPath() 处理路径遍历风险

检查 … 防止路径穿越

使用 normalize() 标准化路径

资源管理:

使用 try-with-resources 自动关闭流

流式传输避免内存溢出

异常处理:

明确的HTTP状态码返回

客户端友好错误提示

扩展性:

配置化存储路径

自动创建缺失目录

内容协商:

自动检测MIME类型

支持浏览器直接下载

使用建议:

生产环境需添加:

文件大小限制(application.yml中配置)

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

安全增强:

文件类型白名单校验

病毒扫描

访问权限控制

大文件优化:

分片上传

断点续传

异步处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值