在将文件作为对REST请求的响应返回后,处理删除文件的最佳方法是什么?
我有一个端点,可以根据请求创建文件并在响应中返回它。一旦调度响应,就不再需要该文件,可以/应该删除该文件。
@Path("file")
@GET
@Produces({MediaType.APPLICATION_OCTET_STREAM})
@Override
public Response getFile() {
// Create the file
...
// Get the file as a steam for the entity
File file = new File("the_new_file");
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition", "attachment; filename=\"the_new_file\"");
return response.build();
// Obviously I can't do this but at this point I need to delete the file!
}
我想我可以创建一个tmp文件,但我认为有更优雅的机制来实现这一目标。该文件可能非常大,因此我无法将其加载到内存中。
答案 0 :(得分:11)
将StreamingOutput用作实体:
final Path path;
...
return Response.ok().entity(new StreamingOutput() {
@Override
public void write(final OutputStream output) throws IOException, WebApplicationException {
try {
Files.copy(path, output);
} finally {
Files.delete(path);
}
}
}
答案 1 :(得分:9)
有一个更优雅的解决方案,不写文件,只是直接写入Response
实例中包含的输出流。
答案 2 :(得分:1)
在不知道应用程序的上下文的情况下,您可以在VM退出时删除该文件:
file.deleteOnExit();
请参阅:https://docs.oracle.com/javase/7/docs/api/java/io/File.html#deleteOnExit%28%29
答案 3 :(得分:0)
我最近在使用球衣的休息服务开发中做了类似的事情
@GET
@Produces("application/zip")
@Path("/export")
public Response exportRuleSet(@QueryParam("ids") final List<String> ids) {
try {
final File exportFile = serviceClass.method(ruleSetIds);
final InputStream responseStream = new FileInputStream(exportFile);
StreamingOutput output = new StreamingOutput() {
@Override
public void write(OutputStream out) throws IOException, WebApplicationException {
int length;
byte[] buffer = new byte[1024];
while((length = responseStream.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
out.flush();
responseStream.close();
boolean isDeleted = exportFile.delete();
log.info(exportFile.getCanonicalPath()+":File is deleted:"+ isDeleted);
}
};
return Response.ok(output).header("Content-Disposition", "attachment; filename=rulset-" + exportFile.getName()).build();
}
答案 4 :(得分:-1)
将响应保存在tmp变量中,并替换return语句,如下所示:
Response res = response.build();
//DELETE your files here.
//maybe this is not the best way, at least it is a way.
return res;
答案 5 :(得分:-1)
在回复时发送文件名:
return response.header("filetodelete", FILE_OUT_PUT).build();
之后你可以发送删除restful方法
@POST
@Path("delete/{file}")
@Produces(MediaType.TEXT_PLAIN)
public void delete(@PathParam("file") String file) {
File delete = new File(file);
delete.delete();
}