본문 바로가기
JAVA공부/0-자바기초(초급자)

[File]자바 파일 변환하기 / 자바 파일 컨버팅하기/ MultipartFile File 변환하기 - 자바 파일을 컨버팅해보자

by 으노으뇨 2023. 12. 3.
728x90
반응형
SMALL

안녕하세요~!! ㅎㅎㅎ

오랜만에 찾아 뵙겠습니다.

주말동안 큰일을 당하고 ...

주말 푹쉬지못하고...

기꺼이 정신 조금 차리고 글을 쓰게 되네요 ㅎㅎㅎ


학습 성과

  1. Spring의 MulipartFile활용 : 멀티파트 객체를 이용하여 클라이언트에서 업로드한 파일을 다루는 방법을 배웠습니다.
  2. File I/O 처리 : 파일을 생성하고, 파일에 데이터를 기록하고 확인하는 방법을 학습했습니다.
  3. 파일 시스템 및 속성 조회 : 파일의 상태와 속성을 확인하고 그에 따른 예외적인 상황이나 케이스를 확인했습니다.

이를 통해 파일 업로드 및 자바의 파일 I/O 처리 기술을 이해하고 활용하는 방법을 학습했으며, 파일 시스템을 다루고 파일의 상태를 확인하는 데 많은 성과를 얻었습니다.


이번엔 제가 최근에 혼자 개발하면서 공부한 내용입니다.

우선 제가 

MultipartFile 인터페이스 를 File 클래스로 변환하고자 공부했던 내용을 조금 정리하겠습니다.

우선 해당 기능의 필요성은 제가 Spring 기반으로 개인프로젝트 웹개발을 진행 중

클라이언트로 부터 MultipartFile 로 받아온 파일을

이제 엑셀로 다루기 위해서는 File 클래스의 객체로 변환이 필요했었습니다.


인터넷에 찾아보니까 

	public static File multipartFileToFile(MultipartFile file) throws IOException
	{
		File convFile = new File(file.getOriginalFilename());
		convFile.createNewFile();
		FileOutputStream fos = new FileOutputStream(convFile);
		fos.write(file.getBytes());
		fos.close();
		return convFile;
	}

이런식으로 코드를 작성하더군요

아 물론, 이 코드가 잘못되었다는 것은 아닙니다.

당장 급하고 필요하신 분들은 이 소스를 복사하고 붙여 놓으시고,

대강 설명을 드리자면

1. 클라이언트로 부터 받아온 MultipartFile 객체를 매개변수로 받는 매서드

2. 매개변수의 MulipartFile 객체를 File 객체 생성하나, 생성자에 매개변수의 실제파일이름을 넣는다.

3. 파일 클래스의 파일 만드는 메서드를 이용해서 생성하고

4. FileOutStream 클래스를 이용해서 해당 파일에 바이트들을 넣어준다.

5. 그리고 그렇게 바이트들을 주입받은 파일을 리턴 값으로 내보난다.

이렇게 진행되는 로직입니다. 틀리면 댓글로 꾸짖고 욕해주세요.;;; 저도 처음 코딩하는 지라 잘 모른답니다...


조상님들이 작성하고 수 많은 사람들이 위와 같은 코드를 작성해서 

저는 한가지 의문점이 들었습니다.

이미 File 생성자에 file.getOriginalFilename() 을 넣어서 생성하면 어떤상태일까? 이때도 파일이지 않을까?

라는 의문이 들었습니다.

그래서 아래의 작성된 내용들은 해당 소스를 탐구한 내용입니다.


스스로 가설을 세워보고 확인해보기

1. 이미 file.getOriginalFilename() 를 입력받았을 때부터 파일형태이지 않을까?

2. 1이 참이라면 그냥 진짜 파일이름을 String형태로 하드코딩으로 넣어서 사용해도 될까?

3-1. 2가 참이라면 어떤이유일까?

3-2. 2가 거짓이라면 file.getOriginalFilename()도 하나의 String형태의 객체일 뿐인데 무슨일일까?

이렇게 3가지로 나누어서 진행해보겠습니다.


실습에 앞서서..

우선 간단하게 진행될 에제는 https://uno-kim.tistory.com/212

 

네이버 금융 크롤링 : 주식 종목 엑셀로 최신화 하기

안녕하세요 ~! ㅎㅎㅎㅎ 오늘은 주식 종목으로 엑셀로 최신화 하는 방법에 대해서 알아보겠습니다.!!ㅎㅎㅎ https://uno-kim.tistory.com/211 네이버 금융 크롤링 : 주식 종목 DB 가져오기 안녕하세요~! ㅎ

uno-kim.tistory.com

로 진행될 예정이며 

위 파일로 진행하겠습니다.

253kb, 엑셀 파일, data_2032_20221027.xlsx 입니다.


1. 이미 file.getOriginalFilename() 를 입력받았을 때부터 파일형태이지 않을까?

우선 생성된 파일객체가

파일인가?

읽을 수 있는가?

쓸 수 있는가?

존재하는가?

용량은?

그럼 해당 파일의 콘텐트 파일은?

이렇게 진행하겠습니다. 

안전하게 디버깅 모드로 하나하나 값을 확인하면서 진행하겠습니다.

소스는 이렇습니다.

	public static File multipartFileToFile(MultipartFile file) throws IOException
	{
		File convFile = new File(file.getOriginalFilename());
		boolean isFile = convFile.isFile();
		boolean canRead = convFile.canRead();
		boolean canWrite = convFile.canWrite();
		boolean exists = convFile.exists();
		long length = convFile.length();
		String contentType = Files.probeContentType(convFile.toPath());
		return convFile;
	}

무슨 자신감인지 모르겠지만 우선 리턴값으로 바로 생성된 객체를 반환하는 메소드이며,

확인차원으로 각 속성들의 객체들을 만들었습니다. 확인해보겠습니다.

디버깅 시작!

잘잡혔습니다.

해당 file.getOriginalFilename() 에도 원래 파일이름이 잘 들어왔습니다.

그리고 Expressions를 통해서 확인해보면

앞에서 진행된 확인은 모두 true이며, 심지어 콘텐트타입도 시트(엑셀) 형태로 잘 나왔습니다.

그리고 쭉쭉진행해서 한번 이렇게 생성 파일객체가 정상적으로 작동할수 있을지 

엑셀파일을 다루는 클래스의 소스에서 확인해보겠습니다.

잠깐 보여질 소스는 https://uno-kim.tistory.com/212 에서 보실수 있습니다.

 

네이버 금융 크롤링 : 주식 종목 엑셀로 최신화 하기

안녕하세요 ~! ㅎㅎㅎㅎ 오늘은 주식 종목으로 엑셀로 최신화 하는 방법에 대해서 알아보겠습니다.!!ㅎㅎㅎ https://uno-kim.tistory.com/211 네이버 금융 크롤링 : 주식 종목 DB 가져오기 안녕하세요~! ㅎ

uno-kim.tistory.com

정상적으로 들어왔네요?!

그리고 쭉쭉넘어가 엑셀역할을 하는지 보겠습니다.

쭉쭉보니

와우!!! 익숙한 회사이름, 포스코엠텍이 나왔습니다.

최초 File convFile = new File(file.getOriginalFilename());

File convFile = new File(file.getOriginalFilename());

이렇게 생성한 파일객체가 파일구실도 하는군요... 다음 

2번 가설을 진행해보겠습니다.


2. 진짜 파일이름을 String형태로 하드코딩으로 넣어서 사용해도 될까?

벌써 궁금하네요 ㅎㅎㅎ

소스는

	public static File multipartFileToFile(MultipartFile file) throws IOException
	{
		// final String FILE_REAL_NAME = file.getOriginalFilename();
		final String FILE_REAL_NAME = "data_2032_20221027.xlsx";
		if(file.getOriginalFilename().equals(FILE_REAL_NAME))
		{
			System.out.println("");
		}
		File convFile = new File(FILE_REAL_NAME);
		boolean isFile = convFile.isFile();
		boolean canRead = convFile.canRead();
		boolean canWrite = convFile.canWrite();
		boolean exists = convFile.exists();
		long length = convFile.length();
		String contentType = Files.probeContentType(convFile.toPath());
		return convFile;
	}

위와 같이 짰으며 한번 IF 문을 통해서 파일 이름과 하드코딩된 파일이름이 같은지 판단하고 넘겼습니다. 

그냥 확인로직이니 크게 신경안쓰셔도 될것같습니다.

디버깅 진행해보겠습니다! ㅎㅎ

우선 하드코딩된 파일이름이 대충 같다는 결과로 조건문을 지나갑니다.

우선 들어왔네요... 두근두근

엥????

엑셀로도 잘읽힙니다...?

 

제가 잘못보고있는걸까요,,,

바로다음 3-2 번으로 넘가겠네요 ... 무슨일일까...?

그럼 파일을 인식 못하게끔 억지로 다른 파일을 넣으면 어떻게 될까요????


3-2. 진짜 이게 무슨일이지...? 완전 다른파일이름을 하드코딩으로 해보자

파일을 동일하게 하나 더 생성했습니다.

하나는 파일이름 마지막이 6이고, 업로드할 파일은 마지막이 7입니다.

1. 하드코딩에는 마지막글자가 6인 파일이름으로 코딩

2. 업로드는 마지막글자가 7인 파일이름으로 코딩

3. 두근두근 진행

	public static File multipartFileToFile(MultipartFile file) throws IOException
	{
		final String MULTIFILE_REAL_NAME = file.getOriginalFilename();
		final String FILE_REAL_NAME = "data_2032_20221026.xlsx";
		if(file.getOriginalFilename().equals(FILE_REAL_NAME))
		{
			System.out.println("");
		}
		File convFile = new File(FILE_REAL_NAME);
		boolean isFile = convFile.isFile();
		boolean canRead = convFile.canRead();
		boolean canWrite = convFile.canWrite();
		boolean exists = convFile.exists();
		long length = convFile.length();
		String contentType = Files.probeContentType(convFile.toPath());
		return convFile;
	}

소스는 이렇게 작성했습니다.

		final String MULTIFILE_REAL_NAME = file.getOriginalFilename();
		final String FILE_REAL_NAME = "data_2032_20221026.xlsx";

실제 업로드된 파일이름을 얻기위한 상수데이터를 선언,

그리고 하드코딩 상수데이터 선언,

실제업로드된 파일이름과 하드코딩된 파일이름이 같은지 조건문을 통해 확인,

그리고 쭉쭉쭉 확인절차 진행

이렇게 진행되게 작성했습니다.

한번 확인 진행해보겠습니다.

음.... 파일이아니고, 읽지못하고 용량도 없고 그런데 마지막은 sheet...ㅋㅋㅋㅋㅋ

저기 위에 소스대로 하면 저렇게 좀비파일도 살릴수있나? 입니다. ㅎㅎㅎ


4. 인터넷에 떠도는 소스로 작성하면 3-2번의 소스같은 좀비파일을 진짜 파일로 만들 수 있을까?

인터넷소스를 검증해보겠습니다.

소스는 아래와 같습니다.

	public static File multipartFileToFile(MultipartFile file) throws IOException
	{
		/* 실제 업로드된 파일 이름을 상수형으로 저장 */
		final String MULTIFILE_REAL_NAME = file.getOriginalFilename();
		/* 아무이름이로 상수형으로 저장 - 업로드하는 파일의 같은 경로에 실제 존재하긴하는 파일이름 */
		final String FILE_REAL_NAME = "data_2032_20221026.xlsx";
		/** 
		 * 실제업로드된 파일이름과 하드코딩한 파일이름 비교
		 * @True	: 파일명이 같다.
		 * @False	: 파일명이 다르다.
		 */
		if(MULTIFILE_REAL_NAME.equals(FILE_REAL_NAME))
		{
			System.out.println("");
		}
		/* 하드코딩된 파일이름으로 파일하나 생성(아무것도 안들어있다.) */
		File convFile = new File(FILE_REAL_NAME);
		/** 
		 * @author	: 인터넷에 떠도는 소스
		 * @Desc  	: 파일을 새로 생성하는듯하다.
		 */ 
		convFile.createNewFile();
		/** 
		 * @author	: 인터넷에 떠도는 소스
		 * @Desc  	: 우선 파일아웃스트림으로 작성되어질 파일을 객체로 생성하는것 같다.
		 */ 
		FileOutputStream fos = new FileOutputStream(convFile);
		/** 
		 * @author	: 인터넷에 떠도는 소스
		 * @Desc  	: fos에 file(클라이언트로 부터 받아온 MultipartFile file 매개변수)의 바이트정보를 주입
		 */ 
		fos.write(file.getBytes());
		fos.close();
		/** 
		 * @author	: uno-kim
		 * @Desc  	: 확인절차
		 */ 
		boolean isFile = convFile.isFile();
		boolean canRead = convFile.canRead();
		boolean canWrite = convFile.canWrite();
		boolean exists = convFile.exists();
		long length = convFile.length();
		String contentType = Files.probeContentType(convFile.toPath());
		return convFile;
	}

주석으로 아~~~~주 친절하게 작성했습니다.

인터넷에 떠도는 소스에는 어떤 의미로 사용했는지 설명이 부족해서 

저의 짧은 가방끝으로 가까스로 스스로 생각해낸 추측?입니다. 우선은 확인을 통해서 추측이 맞는지 봐야하니까요...

인터넷에 떠도는 소스에 조금 설명만 있었어도 덜 헤맷을텐데 ㅎㅎㅎ

진행해 보겠습니다.

원래 제 소스대로 확인절차 이후 -> 파일아웃스트림으로 데이터 주입 -> 그리고 다시 데이터 확인절차 -> 엑셀데이터 확인

이렇게 진행하겠습니다.

과연 어떻게 되었을까요?!!

와우!!!

인터넷에 떠도는 소스가 유령소스는 아니었군요!!! ㅎㅎㅎ빈 파일을 생성하고 거기에 멀티파일을 넣는 식으로 진행하고있군요

선조님들 굉장합니다...

뭐 저도 개발시작한지 얼마 안되었지만,,

학습하는 좋은 계기가 되었습니다. 

쓸모없는글 끝까지 읽어주셔거 감사합니다.!!!!!

728x90
반응형
LIST

댓글