개발/Java&Kotlin

[Java] File 입출력

devhooney 2023. 1. 13. 09:16
728x90

1. 개념

- 파일은 가장 많이 사용되는 입출력 대상

- File 클래스를 통해 파일과 디렉토리를 다룰 수 있음.

 

- window에서 예시 코드

import java.io.*;

class FileExample {
    public static void main(String[] args) throws IOException {
        
        File f = new File("경로");
        
        String fileName = f.getName();
        int pos = fileName.lastIndexOf(".");
        
        System.out.println("경로 제외한 이름 " + f.getName());
        System.out.println("확장자 제외한 이름 " + fileName.substring(0, pos));
        System.out.println("확장자 " + fileName.substring(pos+1));
        
        System.out.println("경로를 포함한 파일 이름 " + f.getPath());
        System.out.println("파일의 절대경로 " + f.getAbsolutePath());
        System.out.println("파일의 정규경로 " + f.getCanonicalPath());
        System.out.println("파일이 속해 있는 디렉토리 " + f.getParent());
        
        
    }
}

- File 인스턴스를 만든다고 파일이이나 디렉토리가 만들어지는 것은 아님.

- 이미 존재하는 파일을 참조할 때

File f = new File("경로");

- 기존에 없는 파일을 생성할 때

File f = new File("경로");
f.createNewFile();

 

 

 

728x90

 

 

 

2. 파일 다운로드

response Flush

public void downloadFile(Long param, HttpServletResponse response) throws Exception {
    Map<String, Object> map = fileService.selectFileInfo(param);
    String originalFileName = (String) map.get("ORIGINAL_FILE_NAME");
    String storedFileName = (String) map.get("STORED_FILE_NAME");
    
    byte[] fileByte = FileUtils.readFileToByteArray(new File("경로" + storedFileName));
    
    // 파일 유형
    response.setContentType("application/octet-stream");
    
    // 파일 길이
    response.setContentLength(fileByte.length);
    
    // 데이터 형식
    response.setHeader("Content-Disposition", "attachment; fileName=\"" + URLEncoder.encode(originalFileName, "UTF-8") + "\";");
    
    // 인코딩
    response.setHeader("Content-Transfer-Encoding", "binary");
    
    // 버퍼 출력 스트림
    response.getOutputStream().flush();
    
    // 출력스트림 close
    response.getOutputStream().close();
    
    
}

 

- response.setContentType()

  • 파일유형을 설정
  • 웹서버는 브라우저로 전송될 페이지가 html인 경우 text/html을 표준 MIME타입으로 지정함
  • MIME타입을 변경 또는 인코딩셋을 변경하고자 할때, setContentType메소드를 사용
  • octet-stream은 8비트 바이너리배열을 의미하며, http나 email상에서 application이 지정되지 않았거나 형식을 모를때 사용
  • 브라우저는 octet-stream으로 MIME타입이 지정된 경우 바이너리 데이터로만 다운로드가 가능하게 됨
    • HTML로 출력시 : setContentType("text/html");
    • 일반 TEXT로 출력시 : setContentType("text/plain");
    • 이미지 GIF로 출력시 : setContentType("image/gif");
    • 이미지 JPG, JPEG로 출력시 : setContentType("image/jpeg");

 

- response.setHeader("Content-Disposition", "attachment; fileName=~~~;)

  • Content-Disposition은 HTTP Response Body에 오는 컨텐츠의 기질/성향을 알려주는 속성
  • Default값은 inline으로 웹에 전달되는 data
  • Content-Disposition에 attachment를 주는 경우, Body에 오는 값을 다운로드 받으라는 뜻
  • attachment는 첨부파일을 의미.
  • fileName은 다운로드할때의 파일이름을 의미.
  • UTF-8인코더는 한글변환을 위함
  • attachment;와 fileName 사이에는 띄워쓰기를 꼭 해주어야 하고 인코드하는 뒤 부분 "\" 부분도 꼭 써줘야 다운로드가 가능.

 

- response.setHeader("Content-Transfer-Encoding", "binary")

  • Content-Transfer-Encoding 는 전송되는 데이터의 안의 내용물들의 인코딩 방식을 의미.

 

- response.getOutputStream().write(fileByte)

  • byte[]타입으로 변환한 파일을 reponse를 통해 client로 보냄
  • Stream은 데이터의 입력과 출력을 하도록 이어주는 통로
  • Stream은 데이터를 보낼때 '임시적으로 모아서 보내줌.' 여기서 임시로 모아두는 공간이 buffer
  • 파일에 data를 쓸때 buffer에 내용을 채운 후 파일에 쓴다.

 

- response.getOutputStream().flush();

  • reponse를 중지
  • flush는 버퍼를 비우는 기능
  • 연속적으로 data를 쓸 경우 buffer가 차게되면, 자동으로 flush해준 후 다음 내용을 buffer에다 채움
  • 남아있는 내용을 buffer에 채움

 

- response.getOutputStream().close();

  • reponse를 닫음.
  • close함수 내부적으로 flush함수를 호출하기때문에 flush함수를 안써도 된다.

 

 

728x90