복붙노트

[SPRING] 파일을 웹 앱으로 보낸 후 파일을 삭제하는 방법은 무엇입니까?

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. ==============================

    1.@ResponseBody를 사용하지 마십시오. Spring이 HttpServletResponse를 삽입하고 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();
    }
    

    예외 처리를 추가하지 않았습니다. 나는 너에게 맡긴다.

    FileSystemResource는 실제로 Spring에서 사용되는 FileInputStream의 래퍼입니다.

    또는 하드 코어가되기를 원한다면, close ()를 호출 할 때 기본 파일을 삭제하는 FileOutputStream 구현을 리턴하는 자체 getOutputStream () 메소드로 자신의 FileSystemResource 구현을 만들 수 있습니다.

  2. ==============================

    2.그래서 소티 어리 어스의 제안을 "하드 코어"방식으로 결정했습니다. 꽤 간단하지만 문제가 하나 있습니다. 해당 클래스의 사용자가 입력 스트림을 한 번 열어 닫은 다음 입력 스트림을 열면 닫을 때 파일이 삭제되므로 다시 열 수 없습니다. Spring은 그렇게하지 않는 것 같지만 모든 버전 업그레이드가 끝나면 확인해야합니다.

    그래서 소티 어리 어스의 제안을 "하드 코어"방식으로 결정했습니다. 꽤 간단하지만 문제가 하나 있습니다. 해당 클래스의 사용자가 입력 스트림을 한 번 열어 닫은 다음 입력 스트림을 열면 닫을 때 파일이 삭제되므로 다시 열 수 없습니다. 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();
            }
        }
    }
    
  3. ==============================

    3.이 답변에 약간의 적응.

    이 답변에 약간의 적응.

    FileSystemResource 대신 InputStreamResource를 사용하면 조금 더 짧아집니다.

    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());
                }
            });
        }
    }
    
  4. from https://stackoverflow.com/questions/17933508/how-to-delete-a-file-after-sending-it-in-a-web-app by cc-by-sa and MIT license