본문 바로가기
코딩도전기/I.O.

CODO Day27_JAVA_I.O(Stream/Upload)

by 코도꼬마 2023. 3. 10.

Input & Output

  • InputStream : 외부에서 파일을 읽어올 때 사용
    • Input Stream  >>  read() >>  Output Stream  >  flush()* : (남은 데이터 내보내기)  >>  close()* : (자원 닫기)
  • OutputStrem : 파일을 외부로 내보낼 때 사용 
    • Reader  >>  read() >>  Writer  flush()* : (남은 데이터 내보내기)  >>  close()* : (자원 닫기)*

 

# flush()* 해주지 않으면  stream에 데이터가 남아 있어 파일이 정상적으로 실행되지 않을 수 있음
# close()* 해주지 않으면 접근할 수 있는 자원이 점점 줄어들어 서버 속도가 느려지다가 die...  

 

InputStream 사용 순서

  1. File 객체에 매개변수로 읽어올 디렉토리 경로를 넣어 path를 지정해주고 객체화해줌
  2. 사용할 inputStream 준비(inputStream 객체화)
  3. read()로 data를 읽어와서 담아줌(이때 read()는 값을 하나씩만 가져오기 때문에 while문으로 전체를 빼내주어야함)
  4. close()로 자원을 닫아줌

 

  • ReadController(파일 불러와서 출력하기)
package kr.co.web.controller;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = {"/"})
public class ReadController extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		
		//1.파일위치 지정 >> File 객체화
		File file = new File("C:/img/temp/news.txt");
		
		//2.읽어올 대상(빨대)을 준비(InputStream/Reader)
		FileReader reader = new FileReader(file, Charset.forName("UTF-8"));
		
		//3.읽어옴(byte/char 단위)
		int data;
		StringBuffer text = new StringBuffer();
		
		while((data = reader.read()) != -1) {
			//System.out.print((char)data);
			text.append((char)data);
		}
		
		//4.자원반납(중요!* - 바로 알아차리기 힘듦)
		reader.close();
		
		req.setAttribute("text", text);
		RequestDispatcher dis = req.getRequestDispatcher("result.jsp");
		dis.forward(req, resp);		
	}

}

 

  • result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style></style>
</head>
<body>
	${text}
</body>
<script></script>
</html>

 

 

 

OutputStream 사용 순서

  1. File 객체에 매개변수로 저장할 디렉토리 경로를 넣어서 path를 지정해주고 객체화해줌
  2. 사용할 outputStream 준비(outputStream 객체화)
  3. read()로 data를 읽어와서 대상 파일 or 폴더에 기록(write) (마찬가지로 while문 사용)
  4. flush()  -  stream에 남아있는 데이터를 모두 내보내주고
  5. close()  -  자원 닫기

 

  • WriteController
package kr.co.web.controller;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/write")
public class WriteController extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {		
		req.setCharacterEncoding("UTF-8");
		
		String content = req.getParameter("content");
		//System.out.println(content);
		
		//1.위치지정 + 파일 객체화
		File file = new File("C:/img/temp/user.txt");
		
		//2.빨대 준비(OutputStream/Writer)
		FileWriter writer = new FileWriter(file, Charset.forName("UTF-8"), true);
		
		//3.쓰기
		writer.write(content+"\r\n");
		
		//4.flush() - 내보내기*
		writer.flush();
		
		//5.close() - 자원반납*
		writer.close();		
		
		req.setAttribute("msg", "파일 저장 완료!");
		RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
		dis.forward(req, resp);		
	}

}

 

  • index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style></style>
</head>
<body>
	<form action="write" method="post">
		<input type="text" name="content"/>
		<input type="submit" value="저장"/>
	</form>
	<br/>
	${msg}
</body>
<script></script>
</html>

 

 

 

 

File Upload 순서

  • 사용자 PC에서 서버로 파일을 전송하는 것을 upload라고 함
  • Upload된 파일은 서버PC에 저장되어야 함

 

Upload 순서(얻어온 InputStream으로부터 데이터를 읽어와 OutputStream을 사용해서 서버 PC에 파일저장)

  1. Request로부터 Stream을 뽑아 냄(req로 들어온 params&inputStream 준비)
  2. 내보낼 Stream 준비(outputStream)
  3. InputStream으로부터 data를 읽어옴
  4. 읽어온 data를 OutputStream으로 내보냄
  5. Flush() 후 Close()

 

Upload 규칙

  1.  POST로 전송해야함(data의 크기가 크기 때문)
  2.  보내는 파라메터의 타입이 문자 외에도 여러가지(multipart - text, img...)로 구성되어 있다고 알려야함
  3. 들어오는 파일 크기를 제한해줘야 함(해주지 않으면 파일 받지 않음)
    • fileSizeThreshold : 파일이 디스크에 기록될 때 까지의 크기 임계값(이동 중 공중에서 들고 있을 값)
    • maxFileSize : 업로드할 파일에 허용되는 최대 크기
    • maxRequestSize : multipart/form-data / 문자+파일을 합쳐서 받아줄 최대 크기

 

  • UploadController
package kr.co.web.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jihoon.file.utils.PartsUploadUtil;

@WebServlet("/write")
@MultipartConfig(
		fileSizeThreshold = 10*1024*1024,
		maxFileSize = 50*1024*1024,
		maxRequestSize = 100*1024*1024
		)
public class UploadController extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		
		//받아온 요청을 문자와 파일로 구분
		PartsUploadUtil util = new PartsUploadUtil(req);
		
		HashMap<String, String> params = util.getParams();
		//System.out.println(params);
		
		//파일로부터 스트림을 생성
		InputStream is = util.getStream("photo");
		
		//파일이름 추출
		String fileName = util.getFileName("photo");
		//System.out.println("저장할 파일명 : " + fileName);
		
		
		//여기서부터 중요함*
		//1.파일 위치를 지정 + File 객체를 객체화
		File file = new File("C:/img/"+fileName);
		
		//2.Output stream 객체화
		FileOutputStream fos = new FileOutputStream("C:/img/"+fileName);
		
		//3.읽어온 내용 내보내기
		long start = System.currentTimeMillis();
		int data;
		while((data = is.read()) != -1) {
			fos.write(data);
			System.out.println("복사중..");
		}		
		long end = System.currentTimeMillis();
		
		//4.flush()
		fos.flush();
		//5.close()
		fos.close();
		is.close();
		
		req.setAttribute("msg", ((end-start)/1000)+"초");
		RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
		dis.forward(req, resp);
	}
	
}

 

  • index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style></style>
</head>
<body>
	<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" name=저장/></p>
	</form>
</body>
<script>
	var msg = "${msg}"
	if(msg != ''){
		alert(msg);
	}
</script>
</html>

 

 

 

 

'코딩도전기 > I.O.' 카테고리의 다른 글

CODO Day29_JAVA_NIO(New Input / Output)  (0) 2023.03.14
CODO Day28_JAVA_I.O(SubStream)  (0) 2023.03.13
CODO Day26_JAVA_I.O(JAVA Input Output)  (0) 2023.03.09