java 在网络应用程序中发送文件后如何删除文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17933508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to delete a file after sending it in a web app?
提问by ia.solano
I have a web application. I am using java and spring. The application can create a file and send it to the browser, this is working fine. The way I do it is:
我有一个网络应用程序。我正在使用 java 和 spring。该应用程序可以创建一个文件并将其发送到浏览器,这工作正常。我的做法是:
I create the file in a Services class, and the method returns the address to the controller. The controller then sends the file, and it is downloaded correctly. The code for the controller method is this.
我在服务类中创建文件,该方法将地址返回给控制器。然后控制器发送文件,并正确下载。控制器方法的代码是这样的。
@RequestMapping("/getFile")
public @ResponseBody
FileSystemResource getFile() {
String address = Services.createFile();
response.setContentType("application/vnd.ms-excel");
return new FileSystemResource(new File (address));
}
The problem is that the file is saved in the server, and after many requests it will have a lot of files. I have to delete them manually. The question is: How can I delete this file after sending it? or Is there a way to send the file without saving it in the server?
问题是文件保存在服务器中,多次请求后会出现很多文件。我必须手动删除它们。问题是:发送后如何删除此文件?或者有没有办法发送文件而不将其保存在服务器中?
回答by Sotirios Delimanolis
Don't use @ResponseBody
. Have Spring inject the HttpServletResponse
and write directly to its OutputStream
.
不要使用@ResponseBody
. 让 Spring 注入HttpServletResponse
并直接写入其OutputStream
.
@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();
}
I haven't added any exception handling. I leave that to you.
我没有添加任何异常处理。我把它留给你。
FileSystemResource
is really just is a wrapper for FileInputStream
that's used by Spring.
FileSystemResource
实际上只是FileInputStream
Spring 使用的包装器。
Or, if you want to be hardcore, you could make your own FileSystemResource
implementation with its own getOutputStream()
method that returns your own implementation of FileOutputStream
that deletes the underlying file when you call close()
on it.
或者,如果您想成为铁杆,您可以FileSystemResource
使用自己的getOutputStream()
方法创建自己的实现,该方法返回您自己的实现,FileOutputStream
当您调用close()
它时会删除底层文件。
回答by Mag
So I decided to take Sotirious's suggestion for a "hardcore" way. It is pretty simple, but has one problem. If user of that class opens input stream once to check something and closes it, it will not be able to open it again since file is deleted on close. Spring does not seem to do that, but you will need to check after every version upgrade.
所以我决定采纳 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();
}
}
}
回答by kuhnroyal
A minor adaption to this answer.
对这个答案的小改动。
Using a InputStreamResource
instead of FileSystemResource
makes this a little shorter.
使用 aInputStreamResource
而不是FileSystemResource
使这更短。
public class CleanupInputStreamResource extends InputStreamResource {
public CleanupInputStreamResource(File file) throws FileNotFoundException {
super(new FileInputStream(file) {
@Override
public void close() throws IOException {
super.close();
Files.delete(file.toPath());
}
});
}
}