在Web应用程序中发送文件后如何删除文件?

我有一个 Web 应用程序。我正在使用java和spring。应用程序可以创建一个文件并将其发送到浏览器,这工作正常。我这样做的方式是:

我在 Services 类中创建该文件,该方法将地址返回给控制器。然后,控制器发送文件,并正确下载该文件。控制器方法的代码是这样的。

@RequestMapping("/getFile")
public @ResponseBody
FileSystemResource getFile() {

    String address = Services.createFile();
    response.setContentType("application/vnd.ms-excel");
    return new FileSystemResource(new File (address));
}

问题是文件保存在服务器中,并且在多次请求之后,它将具有很多文件。我必须手动删除它们。问题是:发送后如何删除此文件?或者有没有办法在不将其保存在服务器中的情况下发送文件?


答案 1

不要使用 .让 Spring 注入 并直接写入其 .@ResponseBodyHttpServletResponseOutputStream

@RequestMapping("/getFile")
public void getFile(HttpServletResponse response) {
    String address = Services.createFile();
    File file = new File(address);
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-disposition", "attachment; filename=" + file.getName());

    OutputStream out = response.getOutputStream();
    FileInputStream in = new FileInputStream(file);

    // copy from in to out
    IOUtils.copy(in,out);

    out.close();
    in.close();
    file.delete();
}

我没有添加任何异常处理。我把它留给你们。

FileSystemResource真的只是一个包装器,这是春天使用的。FileInputStream

或者,如果你想成为硬核,你可以使用自己的方法创建自己的实现,该方法返回你自己的实现,当你调用它时,它会删除基础文件。FileSystemResourcegetOutputStream()FileOutputStreamclose()


答案 2

所以我决定接受Sotirious的建议,以一种“硬核”的方式。这很简单,但有一个问题。如果该类的用户打开一次输入流以检查某些内容并关闭它,则它将无法再次打开它,因为文件在关闭时被删除。Spring似乎没有这样做,但是您需要在每次版本升级后进行检查。

public class DeleteAfterReadeFileSystemResource extends FileSystemResource {
    public DeleteAfterReadeFileSystemResource(File file) {
        super(file);
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new DeleteOnCloseFileInputStream(super.getFile());
    }

    private static final class DeleteOnCloseFileInputStream extends FileInputStream {

        private File file;
        DeleteOnCloseFileInputStream(File file) throws FileNotFoundException    {
            super(file);
            this.file = file;
        }

        @Override
        public void close() throws IOException {
            super.close();
            file.delete();
        }
    }
}