쉽게 쉽게

[Java] FILE 업로드(다중) 본문

개발공부/Java

[Java] FILE 업로드(다중)

곱마2 2024. 4. 28. 17:50
반응형

1. File클래스란

java.io 패키지에서 제공하는 File 클래스는 입출력에 필요한 파일 및 디렉터리에 관한 정보를 다를 수 있다.

File 클래스는 파일과 디렉터리의 접근 권한, 생성된 시간, 마지막 수정 일자, 크기, 경로 새로운 파일과 디렉터리 생성 및 삭제, 이름 변경 등의 조작 메드를 가지고 있다.

2. File 생성자 

File(String path) 주어진 문자열 경로를 갖는 File객체 생성
ex) File dir = new File( "C:\\testDir\\test.txt" );
File(String dir, String name) dir와 name문자열을 연결한 문자열로 경로를 생성하여 File객체를 생성
첫번째 매개변수에 디렉터리 경로를 넣고, 그 하위 파일명을 지정하여 생성
ex) File file = new File("C:\\testDir", "test.txt" );
File(File dir, String name) dir의 파일 객체와 name문자열로 경로를 생성하여 File객체를 생성
만약 디렉터리 관련된 File객체가 이미 생성된 경우 첫번째 매개변수로 전달하고 그 하위에 있는 파일명을 문자열로 하여 File객체를 생성

ex) File dir = new File("C:\\testDir");
File file = new File(dir, "test.txt");
File(URI uri) URI를 추상 경로명으로 변환하여 File 객체를 생성합니다.

3. File 메서드 정리

File 조회 메서드

메서드 설명
File getAbsoluteFile() 파일의 절대 경로를 반환
String getAbsolutePath( ) 파일의 절대 경로를 반환
File getCanonicalFile() 파일의 정규 경로를 반환
String getCanonicalPath( ) 파일의 정규 경로를 반환
String getName( ) 파일명을 반환 (경로는 제외)
String getPath() 파일의 경로를 반환
String getParent() 부모 경로에 대한 경로명을 문자열로 반환
File getParentFile() 부모 폴더를 File의 형태로 반환
long getTotalSpace() 하드디스크의 총 용량을 반환
long getUsableSpace() 하드디스크의 사용 가능한 용량을 리턴
long getFreeSpace() 하드디스크의 남은 공간을 반환
int hashCode() hash code를 반환
long lastModified( ) 해당 경로 파일의 최종 수정 일자를 반환
1970년 1월 1일부터 현재까지의 시간을 밀리세컨드 초로 반환
long length( ) 파일의 크기(파일의 길이)를 바이트로 반환
String[] list( ) 특정 디렉토리의 모든 파일과 자식 디렉토리를  문자열 배열로 반환
String[] list(FilenameFilter filter) filter에 만족되는 파일들과 폴더 이름을 문자열 배열로 반환
File[] listRoots() 하드디스크의 루트 경로를 반환
File[] listFiles() 해당 경로의 파일들과 폴더의 파일을 배열로 반환
File[] listFiles(FileFilter filter) filter에 만족되는 파일들과 폴더를 File 배열로 반환
File[] listFiles(FilenameFilter filter) filter에 만족되는 파일들과 폴더를 File 배열로 반환

 

File 생성/수정/삭제 메서드

메서드 설명
boolean createNewFile() 주어진 이름의 파일이 없으면 새로 생성
static File createTempFile(String prefix, String suffix)  default temporary-file 디렉토리에 파일 이름에 prefix와 suffix를 붙여  임시파일을 생성
static File createTempFile(String prefix, String suffix, File directory)  새로운 임시파일을 파일 이름에 prefix와 suffix를 붙여 directory 폴더에 생성
boolean delete()  파일이나 폴더를 삭제
단, 폴더가 비어있지 않으면 삭제할 수 없습니다.
void deleteOnExit()  자바가상머신이 끝날 때 파일을 삭제
boolean mkdir()  해당 경로에 폴더를 만들기
boolean mkdirs()  존재하지 않는 부모 폴더까지 포함하여 해당 경로에 폴더를 만들기
boolean renameTo(File dest)  dest 로 File 이름을 변경

 

File 체크 메서드

메드 설명
boolean exists()  파일의 존재 여부를 리턴
boolean isAbsolute()  해당 경로가 절대경로인지 여부를 리턴
boolean isDirectory()  해당 경로가 폴더인지 여부를 리턴
boolean isFile()  해당 경로가 일반 file 인지 여부를 리턴
boolean isHidden()  해당 경로가 숨김 file 인지 여부를 리턴

 

File 권한 메서드

메드 설명
boolean canExecute()  파일을 실행할 수 있는지 여부를 리턴
boolean canRead()  파일을 읽을 수 있는지 여부를 리턴
boolean canWrite()  파일을 쓸 수 있는지 여부를 리턴
boolean setExecutable(boolean executable)  파일 소유자의 실행 권한을 설정
boolean setExecutable(boolean executable, boolean ownerOnly)  파일의 실행 권한을 소유자 또는 모두에 대해 설정
boolean setReadable(boolean readable)  파일의 소유자의 읽기 권한을 설정
boolean setReadable(boolean readable, boolean ownerOnly)  파일의 읽기 권한을 소유자 또는 모두에 대해 설정
boolean setReadOnly()  파일을 읽기 전용으로 변경
boolean setWritable(boolean writable)  파일의 소유자의 쓰기 권한을 설정
boolean setWritable(boolean writable boolean ownerOnly)  파일의 쓰기 권한을 소유자 또는 모두에 대해 설정

4. File 업로드(다중)

HTML 파일 업로드

file저장한 상황이다.

<form method="post" action="/saveFile" enctype="multipart/form-data">
    <input type="file" id="file1" name="file" />
    <Button type="submit">전송</Button>
</form>

 

컨트롤러에서 호출

file을 저장하는 컨트롤러를 호출한 상황이다.

 @RequestMapping(value="/saveFile" , method=RequestMethod.POST)
    public String saveFile (Model model, MultipartHttpServletRequest request)throws Exception {
	
  	Map<String, Object> parameter = new HashMap<String, Object>(); // 파라미터
	List<MultipartFile> file_list = request.getFiles("file"); //업로드 파일정보
    
	//컨트롤러에서 파일업로드 호출
	List content_list = new ArrayList();
        for ( int i = 0 ; i < file_list.size() ; i++ ) {
                HashMap row = new HashMap();
                MultipartFile file = file_list.get(i);
                 //업로드할 파일과 파일명에 쓰일 type넘기기
                Map file_map = FileUtility.file_upload(file, "test"); 

 if ( file_map.get("file_path") != null && !file_map.get("file_path").toString().equals("") ) {
                      
                        row.put("file_path", file_map.get("file_path"));
                        row.put("file_org_name", file_map.get("file_org_name"));
                        row.put("file_size", file_map.get("file_size"));                       
                    }

 		content_list.add(row);
 }
 
 parameter.put("content_list", content_list);
 
 //파일정보를 담고있는 content_list를 저장하든, 수정하든, 조회하든 사용자가 원하는대로 사용하면된다.
 //예를들어 파일을 저장한다면 파라미터로 넘겨주면된다.
 	reportService.saveFile(parameter);
 
	return "upload/fileUploadResult";
}

File을 가져오는 파라미터 타입에 대한 궁금점(MultipartFile와 MultipartHttpServletRequest란?)

더보기

File 업로드 기능을 구현할 때, 업로드한 파일정보를 받는 방법은 여러 가지가 있다.

그중에서 제공하는 있는 MultipartFile를 사용하는 방법 MultipartHttpServletRequest를 사용하는 방법에 대해 간략히 설명하고자 한다.

 

MultipartHttpServletRequest란?

MultopartHttpServletRequest 인터페이스는 스프링이 제공하는 인터페이스로서, Multipart 요청이 들어올 때 내부적으로 원본 HttpServletRequest 대신 사용되는 인터페이스이다.

MultipartHttpServletRequest 인터페이스는 HttpServletRequest 인터페이스와 MultipartRequest 인터페이스를 상속받고 있다. 

MultipartHttpServletRequest 인터페이스는 HttpServletRequest 인터페이스를 상속받기 때문에 웹 요청 정보를 구하기 위한 getParameter()나 getHeader()와 같은 메서드를 사용할 수 있으며, 추가로 MultipartRequest 인터페이스가 제공하는 Multipart 관련 메서드를 사용할 수 있다.

단점으로는 HttpServletRequest를 사용해서 코드를 구현해야 한다는 점이 있어 spring이 제공하는 MultipartFile를 이용하는 방법이 더 간편하게 사용되고 있다.

 

MultipartFile란?

MultipartHttpServletRequest를 사용해서 파일 업로드를 구현할 수 있지만 스프링이 제공해주는 MultipartFile 인터페이스를 활용함으로써 더욱 쉽게 파일을 단일, 다중으로 업로드를 할 수 있다.

@RequestParam 어노테이션을 함께 사용하여 file 데이터를 직접 다룰 수 있다는 장점이 있다.

단 다중으로 파일을 받아올경우 여러 개의  @RequestParam를 사용해야 하기 때문에, 이 경우에는 커맨드 객체(Command Object) 방식으로 구현하는 것이 좋습니다. (사용자 정의 class)

 

MultipartFile로 받아오는 예시

public String upload(@RequestParam("file") MultipartFile file) throws IOException {

		System.out.println(file.getName()); // 파일의 파라미터 이름
		System.out.println(file.getSize()); // 파일의 사이즈
		System.out.println(file.getOriginalFilename()); // 파일의 실제 이름
		byte[] data = file.getBytes(); // 파일실제  내용
		
		return "success";
	}

 

MulripartFile 주요 메서드

메소드 설명
getName() 파일의 이름을 구한다
getOriginalFilename() 업로드한 파일의 실제이름을 구한다.
isEmpty() 존재여부를 확인한다.(존재하지 않은 경우 true)
getSize() 업로드한 파일의 크기를 구한다.
getBytes() 업로드한 파일 데이터를 구한다.(byte[]로 리턴)
getInputStream() inputStream을 구한다.
transferTo(File dest) 업로드 한 파일 데이터를 지정한 파일에 저장한다.

 

 

file_upload 호출

FileUtility에 정의된 file_upload를 따라 파일 업로드가 진행되는 과정이다. 

public class FileUtility {
	
    // 로그
	private static final Logger logger = Logger.getLogger(FileUtility.class);
	
	/**
	 * 파일업로드
	 * @param file 
	 * @param type (지정경로)
	 * @return
	 */
	public static Map file_upload (MultipartFile file, String type) {
	
    HashMap parameter = new HashMap();
    
    //저장경로    
	String savePath ="";
    String path_type = type;
    //저장파일명
    	String saveFileName = "";
	String originalfileName = "";
    //랜덤값(UUID는 파일의 고유 번호로, 파일명 중복 방지를 위해 적용한다)
	String genId = UUID.randomUUID().toString();
    //오늘날짜
	Date today = new Date();
    	SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
    	String date = formater.format(today);

        // 파일 중복명 처리
        // 본래 파일명
        if(file != null){
	    	if(!file.isEmpty()){
            		// 파일경로
	    		String webSavePath1 = "";
	
	    		long fileSize = file.getSize() ; // 파일사이즈 반환
	        	originalfileName = file.getOriginalFilename(); // 업로드되는 파일에서 확장자를 포함한 파일의 이름을 반환
	        	originalfileName = Normalizer.normalize(originalfileName, Normalizer.Form.NFC); // 자소분리 방지
                	saveFileName = originalfileName;
	            	// 확장자만 구하는 방법
	            	String ext = originalfileName.substring(originalfileName.lastIndexOf(".") + 1);
	            
	            // 저장되는 파일 이름
	            try{
	
	            	//저장경로
	            	String fullpath = "test/file_upload/"+path_type + "/" + date;
	            	String realFilePath = "/" + fullpath;
	
	            	File dir = new File(realFilePath);
	            	if( !dir.exists() ){
	            		dir.mkdirs();
	            	}
	            		
	                savePath = realFilePath + "/" + genId; // 저장 될 파일 경로
	                file.transferTo(new File(savePath)); // 파일 저장
	                webSavePath1= "/" + fullpath + "/"+ genId;       
	                
	            }
	            catch(Exception e){
	            	logger.error("FileUtility file_upload error : {}", e);
	            }
	            
	    		parameter.put("file_path", webSavePath1);
	    		parameter.put("file_org_name", originalfileName);
	    		parameter.put("file_size", fileSize);
	    	}
        }
    	
    	return parameter;
	}
}

 

자소분리 방지를 하는 이유(Normalizer)

더보기

getOriginalFilename() 메서드는 OS마다 파일 이름을 다르게 처리한다.

특히 맥(Mac)에서 getOriginalFilename() 메서드를 사용하면, 한글의 자음과 모음을 분리한다.

 

테스트. png를 처리하는 차이를 예시로 보면 아래와 같다. 

// 맥(Mac)에서 getOrginalFilename() 한글 처리 방식
["ㅌ", "ㅔ", "ㅅ", "ㅡ", "ㅌ", "ㅡ", ".", "p", "n", "g"]

// 윈도우(Window)에서 getOrginalFilename() 한글 처리 방식
["테", "스", "트", ".", "p", "n", "g"]

 

DB에 Insert 된 파일명의 문자열은 "테스트"로 보이지만, 한글의 자음과 모음이 분리된 상태로 Insert 되었기에 Like 연산자가 동작하지 않는다.

 

이런 문제를 해결하기 위해

정규화 기능을 제공하는 Normalizer 클래스의 normalize() 메서드를 호출하여 NFC 형태로 정규화한다.

* NFC란 GNU/Linux, Windows에서 사용하는 정규화 방식, MAC은 NFD방식을 사용

originalfileName = Normalizer.normalize(originalfileName, Normalizer.Form.NFC); // 자소분리 방지

 

https://developer-talk.tistory.com/811

 

[Java]MultipartFile 파일 이름 가져오는 방법

MultipartFile 파일 이름 가져오는 방법 이번 포스팅은 MultipartFile 형식으로 파일 업로드했을 때, 파일 이름을 가져오는 방법을 소개합니다. getOriginalFilename 메서드 파일 이름을 가져오는 방법은 상당

developer-talk.tistory.com

 

출처

https://panbong-development.tistory.com/entry/File-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

 

File 클래스란 무엇인가

File 클래스 java.io 패키지에서 제공하는 File 클래스는 파일 및 폴더(디렉토리) 정보를 제공해주는 역할을 합니다. 객체 생성 방법은 다음과 같습니다. File file = new file("C:/Temp/file.txt"); File file = new F

panbong-development.tistory.com

https://devbox.tistory.com/entry/Java-File-%ED%81%B4%EB%9E%98%EC%8A%A4

 

[Java] File 클래스

File 클래스 자바에서는 File 클래스를 통해서 파일과 디렉터리를 다룰 수 있도록 하고 있다. 그래서 File 인스턴스는 파일 일 수도 있고 디렉터리 일 수도 있다. 1. File 클래스 API - 경로와 관련된 Fil

devbox.tistory.com

https://www.devkuma.com/docs/java/file-class/

 

Java java.io 패키지 File 클래스

File 클래스는 입출력에 필요한 파일 및 디렉터리에 관한 정보를 다를 수 있다. File 클래스는 파일과 디렉터리의 접근 권한, 생성된 시간, 마지막 수정 일자, 크기, 경로 등의 정보를 얻을 수 메소

www.devkuma.com

https://codedragon.tistory.com/6324

 

File 클래스의 주요 메서드, 분류별 File 클래스의 메소드- File 생성/수정/삭제 메소드, File 체크 메

File 클래스의 주요 메서드exists( )의 반환값이 false이면 createNewFile(), mkdir(), mkdirs()메소드로 파일 또는 디렉토를 생성할 수 있습니다.exists( )의 반환값이 true이면 파일에 대한 정보를 확인할 수 있

codedragon.tistory.com

https://devbox.tistory.com/entry/Spring-파일업로드-처리

 

[Spring] 파일업로드 처리

파일 업로드 처리 인코딩 타입이 Multipart인 경우 파라미터나 업로드한 파일을 구하려면 전송 데이터를 알맞게 처리해 주어야 한다.스프링은 Multipart 지원 기능을 제공하고 있기 때문에, 이 기능

devbox.tistory.com

https://caileb.tistory.com/152

 

MultipartFile을 사용한 File 업로드 (multipart/form-data)

MultipartFile을 사용한 File 업로드 (multipart/form-data) SpringFramework환경의 서버라면 SpringFramework에서 제공하고 있는 MultipartFile 클래스와 MultipartHttpServletRequest 클래스를 사용해서 File 업로드 기능을 구현

caileb.tistory.com

잘못된 내용이 있다면 지적부탁드립니다. 방문해주셔서 감사합니다.
반응형

'개발공부 > Java' 카테고리의 다른 글

[Java] 최대공약수, 최소공배수 구하기  (0) 2024.09.20
[Java] 약수의 개수 구하기  (0) 2024.09.15
Map에 있는 값 형변환하기  (1) 2023.11.19
입출력I/O  (0) 2023.03.31
스트림  (0) 2023.03.31