Spring

국비코딩 Mar10 | stream을 통해 파일을 읽고, 저장하는 과정 / 파일 전송시 규칙 3가지 / 보조스트림 Buffer

onnnzeoz 2023. 3. 10. 17:47

Stream

우리 시스템(ex 자바) 안으로 또는 밖으로 이동하는 data의 흐름

JAVA.io 에는 InputStream과 OutputStream으로 나뉜다

그리고 바이트기반(1 0 1 1...), 문자 기반(a b c d e r...)으로 나뉜다

바이트 기반은 InputStream과 OutputStream 클래스를 사용하고 문자기반은 Reader클래스와 Wirter클래스를 사용함

 

InputStream은 최상위 클래스이고 이걸 직접 사용하는 일은 드뭄 -> FileInputStream BufferedInputStream DataInputStream을 사용함 (OutputStream도 동일한 하위 클래스가 있음)

 

File 객체

JAVA.io에 해당하는 클래스는 아님, file이나 directory를 다룰 수 있게 해주는 객체

File에 Data를 읽고 쓰는 기능은 Stream을 통해 이뤄짐 

File file = new File(“파일 경로”);

ex) File file = new File(“c:\Temp\file.txt”);

file.createNewFile()새 파일 생성

file.mkdir() 새 디렉토리 생성

file.mkdirs() 디렉토리 경로 생성

file.delete() 파일 또는 디렉토리 삭제

 

파일을 읽는 과정

1. 파일 위치 설정

2. 파일 객체화한다

3. 읽어올 때 필요한 stream을 준비한다(Reader)

4. 한글자씩 읽고 출력

5. close

 

파일을 내보내는 과정

1. 파일 위치 설정

2. 파일 객체화

3. 저장할 때 필요한 stream 준비(Writer)

4. 한글자씩 기록

5. flush -> close

flush

output 한 후 끝까지 한걸 마무리하기 위해 싹 털어주는

 

문자열과 바이너리(파일)을 분리해주는 라이브러리를 사용해야함

파일을 outputstream을 통해 서버에 저장시켜야함 

 

inputstream으로 데이터 읽고 outputstream으로 서버pc에 파일 저장하기

1. request로 부터 stream을 뽑아낸다

2. 내보낼 스트림

3. inputStream에서 가져온 내용을

4. ouputStream에서 while문을 통해 읽어줌, read()가 -1이 될 때까지 write(data)를 통해 계속 넣어줘

5. flush후 사용한 자원을 닫는다

6. 그리고 view에 보내주고

//받아온 요청을 문자와 바이너리로 구분
		PartsUploadUtil util = new PartsUploadUtil(req);
		HashMap<String, String> param = util.getParams();
		
		InputStream is = util.getStream("photo"); //inputstream 내놔라
		BufferedInputStream bis = new BufferedInputStream(is); //보조 스트림에 올라탐
		
		String fileName = util.getFileName("photo");
		System.out.println("읽어온 파일"+fileName);
		
		//내보낼 차례
		FileOutputStream fos = new FileOutputStream("C:/img/"+fileName); //stream 만들어주고 여기에 데이터 넣을거임
		//이게 주스트림
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		long start = System.currentTimeMillis();
		
		int data;
		
		while((data = bis.read()) != -1) {
			System.out.println("복사중");
			bos.write(data);
		}
		long end = System.currentTimeMillis();
		bos.flush();
		bos.close();
		bis.close(); 
		//위에서 보조스트림에 주스트림 태웠으면 사용한 곳들에서도 다 바꿔줘야함 flush와 close도 마찬가지
		
		
		req.setAttribute("msg", ((end-start)/1000) +"ms");
		RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
		dis.forward(req, resp);

 

파일 전송시 규칙 3가지

1. doPost 형태로 전송해야한다

2. 보내는 파라메터의 타입이 텍스트와 바이너리 등 여러가지로 구성되어있다고 알려야함(enctype="multipart/form-data")

(두가지 모두 form태그에서)

<form action="write" method="post" enctype="multipart/form-data">
	<p>제목: <input type="text" name="subject"/> </p>
	<p>설명: <input type="text" name="desc"/> </p>
	<p>사진: <input type="file" name="photo"/> </p> 
	<p> <input type="submit" value="저장"/> </p>
	 

</form>

3. 들어오는 파일 크기를 제한해줘야 한다!

fileSizeThreshold : 파일이 디스크에 기록될 때까지의 크기 임계값

(파일 넘겨주는 중간에 몇개나 들고있을래? 10*1024*1024=10메가
maxFileSize : 업로드할 파일에 허용되는 최대 크기
maxRequestSize : multipart/form-data 문자하고 파일하고 다 합쳐서 얼마까지 받아줄 수 있는지?

 

보조스트림

주스트림으론 너무 조금씩밖에 못 옮김 -> 옮기는 속도 느림 -> 보조스트림 탑승해서 속도 키움

보통 2단계정도만

자주 사용하는 보조 스트림 2개

InputStreamReader reader = new InputStreamReader(is)

BufferedReader br = new BufferedReader(reader)

InputStream is = util.getStream("photo"); 
		BufferedInputStream bis = new BufferedInputStream(is); //보조 스트림에 올라탐

inputstream을 통해 "photo" 가져오고 이 주스트림의 변수를 보조스트림에 태움 

FileOutputStream fos = new FileOutputStream("C:/img/"+fileName); //stream 만들어주고 여기에 데이터 넣을거임
		//이게 주스트림
		BufferedOutputStream bos = new BufferedOutputStream(fos);

내보낼 때도 마찬가지 bufferedOutputStream에 태