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

CODO Day29_JAVA_NIO(New Input / Output)

by 코도꼬마 2023. 3. 14.

Java NIO

  • New Input / Output
  • 기존 IO에 Asynchronous와 Channel이라는 개념을 추가
  IO NIO
I/O Stream Channel
Buffer Non-buffer Buffer
Asynchronous X(동기방식) O(비동기방식)
Blocking(Asynchronous와 비슷함) Blocking Blocking/non-blocking

 

# 동기방식 : 여러개의 동작을 실행시켰을 경우 첫번째 동작이 끝나야 다음 동작이 차례대로 실행되는 것
# 비동기방식 : 순서와 상관없이 여러 동작을 한번에 실행시키는 것

 

  • Input / Output Stream을 각각 만들지 않고 하나의 Channel을 활용하거나 Files클래스의 method로 간단히 처리
  • 파일 경로, 정보, 각종 처리 등을 File 객체를 통해 수행하지 않고 각각 다른 클래스로 전문화함
  IO NIO
경로 File Path
파일정보 FileSystem
파일 다루기 Files

 

 

# 아래에서 다룰 FileSystem은 이전에 만들었던 FileSystem과 같으나  I.O. 대신 NIO를 사용

2023.03.09 - [코딩도전기/I.O.] - CODO Day26_JAVA_I.O(JAVA Input Output)

 

  • FileModel(Model의 코드만 변경됨)
package kr.co.web.model;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FileModel {
	
	HttpServletRequest req;
	HttpServletResponse resp;
	RequestDispatcher dis;

	public FileModel(HttpServletRequest req, HttpServletResponse resp) {		
		this.req = req;
		this.resp = resp;		
	}

	public void makeFolder(String path) throws ServletException, IOException {
		//java에서 File이나 Folder를 다룰 땐 File객체가 필요함
		//java nio에서는 파일을 다룰 때 Files 클래스를 사용
		//Paths : static으로 선언되어 객체화x
		Path folderPath = Paths.get(path);
		
		String msg = "이미 존재하는 폴더입니다.";
		
		if(Files.notExists(folderPath)) {
			Files.createDirectories(folderPath);
			msg = "폴더가 생성되었습니다.";
		}

		req.setAttribute("msg", msg);
		dis = req.getRequestDispatcher("index.jsp");
		dis.forward(req, resp);
	}

	public void makeFile(String path) throws IOException, ServletException {
		String msg = "이미 존재하는 파일입니다.";

		
		Path p = Paths.get(path);
		if(Files.notExists(p)) {
			Files.createFile(p);
			msg = "파일이 생성되었습니다.";
		}
		
		req.setAttribute("msg", msg);
		dis = req.getRequestDispatcher("index.jsp");
		dis.forward(req, resp);
	}

	public void fileList(String path) throws ServletException, IOException {
		
		HashMap<String, Object> map = null;
		List<HashMap<String, Object>> list = new ArrayList<HashMap<String,Object>>();
		
		Path dir = Paths.get(path);
		//아래 Stream은 java.io의 Stream이 아님(set과 비슷)
		//set과 비슷하여 iterator로 쪼개서 사용해야함
		Stream<Path> stream = Files.list(dir);
		Iterator<Path> iter = stream.iterator();
		
		while (iter.hasNext()) { //iter에 값이 있으면
			Path info = iter.next();  //쪼갠 값의 key를 가져와 경로로 지정해주고
			map = new HashMap<String, Object>();	
			
			//해당경로의 파일이 디렉토리인지 아닌지를 ture|false 값으로 저장
			map.put("dir", Files.isDirectory(info));  
			map.put("name", info.getFileName());
			map.put("size", Files.size(info));
			list.add(map);
		}
		
		req.setAttribute("path", path);
		req.setAttribute("files", list);
		dis = req.getRequestDispatcher("result.jsp");
		dis.forward(req, resp);
	}

}

 

 

# 아래에서 다룰 FileUpload는 이전에 만들었던 FileSystem과 같으나  I.O. 대신 NIO를 사용

2023.03.10 - [코딩도전기/I.O.] - CODO Day27_JAVA_I.O(Stream/Upload)

 

CODO Day27_JAVA_I.O(Stream/Upload)

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

co-do.tistory.com

 

  • UploadController
package kr.co.web.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
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 = 50*1024*1024, 
				   maxFileSize = 50*1024*1024, 
				   maxRequestSize = 100*1024*1024
				  )
public class Controller extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		PartsUploadUtil util = new PartsUploadUtil(req);
		
		HashMap<String, String> params = util.getParams();
		
		InputStream is = util.getStream("photo");
		BufferedInputStream bis = new BufferedInputStream(is);
		
		String fileName = util.getFileName("photo");		
		
/*		
		FileOutputStream fos = new FileOutputStream("C:/img/"+fileName);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int size = (int) util.getFileSize("photo");
		
		//파일의 사이즈와 같은 크기의 배열을 준비하여 한번에 전송(속도up)
		//서버와 클라이언트가 동일할 경우 가능하나 서버에서 사용할 경우 무리가 있음 
		byte[] arr = new byte[size];
		System.out.println("배열사이즈 : " + size);
		int result = bis.read(arr);
		System.out.println(result);
		bos.write(arr);
		
		bos.flush();
		bos.close();
		bis.close();
*/      
		//N.I.O 사용
		//1.위치지정
		Path path = Paths.get("C:/img/"+fileName);

		int size = (int) util.getFileSize("photo");
		byte[] arr = new byte[size];
		
		//2.파일쓰기
		//APPEND : 이어쓰기
		//CREATE : 파일이 없을 경우
		//CREATE_NEW : 이미 파일이 존재할 경우
		//READ : 읽기모드
		Files.write(path, arr, StandardOpenOption.CREATE);
		bis.close();
		
		req.setAttribute("msg", fileName+"업로드 완료");
		RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
		dis.forward(req, resp);
	}

}

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

CODO Day28_JAVA_I.O(SubStream)  (0) 2023.03.13
CODO Day27_JAVA_I.O(Stream/Upload)  (0) 2023.03.10
CODO Day26_JAVA_I.O(JAVA Input Output)  (0) 2023.03.09