ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [FileSystem] 01. 파일시스템 및 파일업로드
    SsY/Class 2023. 7. 19. 14:01
    728x90
    파일시스템 및 파일업로드
    ■■■ 파일 시스템 및 파일 업로드 ■■■
    
    ○ java.io.FileInputStream 클래스
    
       자바에서는 파일에 대한 바이트 단위 입출력을 수행할 수 있도록 하기 위해
       FileInputStream 클래스와 FileOutputStream 클래스를 제공하고 있다.
       
       ※ FileInputStream 클래스 
          : 시스템의 파일로부터 데이터를 바이트스트림으로 읽어들이기 위해 사용
       ※ FileInputStream 클래스를 이용하여 데이터를 읽어들일 때에는
          데이터 소스인 파일과 직접 연결하여 사용한다.
          (이 때, 지정한 파일이 존재하지 않을 경우 IOException 발생) 
       ※ FileInputStream 클래스는 InputStream 클래스의 하위 클래스이므로
          InputStream 클래스의 기본적인 메소드를 상속받거나 재정의하여 사용한다.
          (InputStream 클래스는 바이트 단위 입력 기능의 최상위 클래스이며 추상 클래스이다.)
          
       - 생성자
         ·FileInputStream(File file)
           : 주어진 File 객체가 가리키는 파일을 바이트스트림으로 읽기 위한 FileInputStream 객체를 생성한다.
         ·FileInputStream(FileDescriptor fdObj)
           : 주어진 FileDescriptor 객체가 가리키는 파일을 바이트스트림으로 읽기 위한 FileInputStream 객체를 생성한다.
         ·FileInputStream(String name)
           : 주어진 이름이 가리키는 파일을 바이트스트림으로 읽기 위한 FileInputStream 객체를 생성한다.
    
    ○ java.io.FileOutputStream 클래스
    
       FileOutputStream 클래스는
       데이터 파일에 바이트스트림으로 저장하기 위해 사용한다.
       파일명이나 File 클래스의 객체를 인수로 넘겨줌으로써 시스템에 파일을 직접 생성할 수 있다.
       기본적으로(default) 파일이 이미 존재한다면 덮어쓰기로 처리되기 때문에 기존의 내용은 사라지게 된다.
       
       ※ FileOutputStream 클래스는 OutPutStream 클래스의 하위클래스이므로
          OutputStream 클래스의 기본적인 메소드를 상속받거나 재정의하여 사용할 수 있다.
          
       - 생성자
         ·FileOutputStream(File file)
           : 주어진 File 객체가 가리키는 파일을 바이트스트림으로 쓰기 위한 FileOutputStream 객체를 생성한다.
             기존의 파일이 존재할 경우 기본적(default)으로 그 내용을 지우고 새로운 파일을 생성하게 된다(덮어쓰기)
         ·FileOutputStream(FileDescriptor fdObj)
           : 주어진 FileDescriptor 객체가 가리키는 파일을 바이트스트림으로 쓰기 위한 FileOutputStream 객체를 생성한다.
             기존의 파일이 존재할 경우 기본적(default)으로 그 내용을 지우고 새로운 파일을 생성하게 된다(덮어쓰기)
         ·FileOutputStream(String name)
           : 주어진 이름이 가리키는 파일을 바이트스트림으로 쓰기 위한 FileOutputStream 객체를 생성한다.
             기존의 파일이 존재할 경우 기본적(default)으로 그 내용을 지우고 새로운 파일을 생성하게 된다(덮어쓰기)
         ·FileOutputStream(String name, boolean append)
           : 주어진 이름이 가리키는 파일을 바이트스트림으로 쓰기 위한 FileOutputStream 객체를 생성한다.
             기존의 파일이 존재할 경우 append로 설정된 값에 따라(true/false) 
             그 내용을 지우고 새로운 파일을 생성하거나 기존의 내용에 추가한다.
    
    ○ java.io.FileReader 클래스
    
       FileReader 클래스는 
       파일에 저장된 바이트를 유니코드 문자로 변환하여 읽어들이고, 
       파일 쓰기 클래스인 FileWriter 클래스는 
       출력할 유니코드 문자열을 시스템에 맞는 디폴트 문자 인코딩방식으로 변환하여 파일에 저장하는 역할을 수행한다.
       
       FileReader 클래스는
       파일에 저장된 문자열을 읽어들이는데 사용되며,
       이 클래스는 InputStreamReader 클래스를 상속한 것으로
       바이트스트림을 읽어서 그 바이트를 유니코드로 나타내는 정수 타입의 값으로 변환해준다.
       
       FileReader 클래스 역시 데이터를 읽어들일 소스인 파일과 직접 연결하여 사용하며, 
       지정한 파일이 존재하지 않을 경우 FileNotFoundException 을 발생시키게 된다.
    
       - 생성자
         ·FileReader(File file)
           : 주어진 File 객체를 이용하여 FileReader 객체를 생성한다.
         ·FileReader(FileDescriptor fd)
           : 주어진 FileDescriptor 객체를 이용하여 FileReader 객체를 생성한다.
         ·FileReader(String fileName)
           : 주어진 이름의 파일을 열어 FileReader 객체를 생성한다.
    
    ○ java.io.FileWriter 클래스
    
       FileWriter 클래스는
       파일 문자 출력스트림으로 출력할 문자를 디폴트 문자 인코딩 바이트로 변환하여
       파일에 저장하고자 할 때 사용한다.
       이 클래스는 OutputStreamWriter 클래스의 서브 클래스로
       유니코드를 바이트로 변환하는 기능을 담당하게 된다.
       FileInputStream 클래스와 마찬가지로 파일명이나 File 클래스의 객체를 인수로 넘겨줌으로써
       시스템에 파일을 직접 생성하게 된다.
       기본적(default)으로 해당 파일이 이미 존재할 경우 덮어쓰기 하게 된다.
    
       - 생성자
         ·FileWriter(File file)
           : 주어진 File 객체를 이용하여 FileWriter 객체를 생성한다.
         ·FileWriter(FileDescriptor fd)
           : 주어진 FileDescriptor 객체를 이용하여 FileWriter 객체를 생성한다.
         ·FileWriter(String fileName)
           : 주어진 이름의 파일을 열어 FileWriter 객체를 생성한다.
         ·FileWriter(String fileName, boolean append)
           : 주어진 이름의 파일 append 의 값(true/false)에 따라
             읽기 / 추가 모드로 열어 FileWriter 객체를 생성한다.
             
    ※ 파일과 디렉터리 관련(관리) 클래스 → java.io.File 클래스
    
        File 클래스는 파일 및 디렉터리를 관리할 수 있도록 기능을 제공해주는 클래스로
        파일의 복사 또는 이름 변경 등의 조작을 할 경우 사용될 뿐
        파일의 내용을 입출력하기 위한 메소드를 제공해주지 않는다.
        자바에서는 모든 데이터의 입출력을 『스.트.림』에 기반하여 수행하기 때문에
        File 클래스는 내부적으로 이러한 메소드를 구현할 필요가 없는 것이다.
        단, File 클래스의 인스턴스는 변경 불가능하다.
        즉, 한 번 생성되면 File 객체에 의해 표현되는 추상 경로명은 절대 변하지 않는다.
        
    ※ 파일 업로드
       
       웹 브라우저를 통해 파일을 전송하기 위해 폼을 구성할 경우
       - form 태그 안에 ... input 태그의 type 속성의 속성값이 
         file 인 태그를 통해 파일을 선택할 수 있는 대화창을 제공한다.
       - 이때, method 속성은 post 를 사용해야하며, 
         enctype 속성의 값은 『"multipart/form-data"』로 지정해야 한다.
       - 단, 『"multipart/form-data"』로 지정한 폼을 전송할 경우
         request 객체로 얻어낸 파라미터 이름으로 값을 얻어낼 수 없다.
         이 말은 『<input type="file">』 로 지정된 파일을 
         서버 상의 특정 경로에 업로드하기 위해서 『특별한 컴포넌트』가 필요하다는 의미이다.
        
    ※ 특별한 컴포넌트 : 『cos.jar』
       - 다운로드 URL : http://www.servlets.com/cos/
       - 다운로드 파일 : cos-22.05.zip(구 cos-20.08/zip)
       - 다운로드 후 압축 해제 > lib 디렉터리 → cos.jar

    fileSystemApp01
    - 경로 확인하기
    <%@page import="java.io.File"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	String appRoot = "/";
    	appRoot = pageContext.getServletContext().getRealPath(appRoot);
    	/* '/'로 구분해서 가져오겠다 */
    	
    	File newFile = new File(appRoot, "data/test.txt");
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>AppRoot.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>관찰</h1>
    	<hr />
    </div>
    
    <div>
    	<h2>웹 어플리케이션 루트 : <%=appRoot %></h2>
    	<!--
    	C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileSystemApp01\
    	//-- 웹 컨텐트에 구성된 것과 같은 형태가 보여지게 됨 -- 이곳이 원본
    	//-- 이클립스에서 보여지는 것은 미러링 된 것
    	-->
    	
    	<h2>생성할 파일 위치 : <%=newFile %></h2>
    	<!--
    	C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileSystemApp01\data\test.txt
    	-->
    	
    </div>
    
    </body>
    </html>

    fileSystemApp02
    - File Wirte/Read 
    • FileWrite.jsp
    <%@page import="java.io.PrintWriter"%>
    <%@page import="java.io.FileWriter"%>
    <%@page import="java.io.File"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	/* 문자 셋 */
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	/* FileWrite.jsp */
    	
    	String appRoot = "/";
    	appRoot = pageContext.getServletContext().getRealPath(appRoot);
    	
    	// 1. 파일을 쓰기 위해 File 객체를 생성
    	File newFile = new File(appRoot, "data/test.txt");
    	
    	// 2. 파일이 존재할 디렉터리가 존재하지 않는 경우
    	//    파일이 위치할 지점까지의 디렉터리를 만들어준다 (생성)
    	if ( !newFile.getParentFile().exists() )
    	{
    		newFile.getParentFile().mkdirs();
    	}
    	
    	// 3-1. 파일을 쓰기 위한 FileWriter 객체 생성
    	FileWriter fw = new FileWriter(newFile);
    	
    	// 3-2. FileWriter 를 좀 더 편하게 사용하기 위해 PrintWriter로 감싸줌
    	PrintWriter pw = new PrintWriter(fw);
    	
    	// 4. 실질적으로 파일에 내용을 기록 (스트림을 통해 출력)
    	pw.println("테스트!");
    	pw.println("확인ㄱㄱ");
    	
    	// 5-1. PrintWriter 리소스 반납(닫아주기)
    	pw.close();
    	
    	// 5-2. FileWriter 리소스 반납(닫아주기)
    	fw.close();
    	
    %>

    • FileRead.jsp
    <%@page import="java.io.BufferedReader"%>
    <%@page import="java.io.FileReader"%>
    <%@page import="java.io.File"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	/* FileRead.jsp */
    
    	// 어플리케이션 루트 확인
    	String appRoot = "/";
    	appRoot = pageContext.getServletContext().getRealPath(appRoot);
    	
    	// 1. 파일을 읽기 위해 File 객체를 생성
    	File newFile = new File(appRoot, "data/test.txt");
    	
    	// 2. 읽어낼 파일이 존재하는지의 여부 확인
    	//    → 파일이 존재하는 경우에만 읽어들이겠다. 
    	//       → FileNotFoundException 방지 
    	if(newFile.exists())
    	{
    		// 3-1. 파일을 읽기 위한 FileReader 객체 생성
    		FileReader fr = new FileReader(newFile);
    		
    		// 3-2. FileReader 를 조금 더 효율적으로 읽어내기 위해
    		//      BufferedReader 로 감싸기
    		BufferedReader br = new BufferedReader(fr);
    		
    		// 4. 실질적으로 파일의 내용을 읽어들이기
    		String readData;
    		while ( (readData=br.readLine()) != null )
    		{//      ======== -------------
    		 //  여기에 담고 | 여기서 읽어온걸   -- 이게 null 이 아니면!
    			out.println(readData + "<br>");
    		}
    		
    		// 5-1. BufferedReader 리소스 반납 (닫아주기)
    		br.close();
    		
    		// 5-2. FileReader 리소스 반납 (닫아주기)
    		fr.close();
    	}
    	
    	/* 해당 파일을 읽어온 결과가 출력되는 것 */
    %>

    fileSystemApp03
    - Object Write / Read (객체 직렬화)
    • ObjectWrite.jsp
    <%@page import="java.io.ObjectOutputStream"%>
    <%@page import="java.io.FileOutputStream"%>
    <%@page import="java.util.Hashtable"%>
    <%@page import="java.io.File"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	/* ObjectWrite.jsp */
    	
    	String appRoot = "/";
    	appRoot = pageContext.getServletContext().getRealPath(appRoot);
    	
    	// 확인
    	System.out.println(appRoot);
    	
    	// 파일 객체 생성
    	File newFile = new File(appRoot, "objData/data.ser");	//-- 확장자 check (객체 직렬화)
    	
    	// 파일이 존재할 디렉터리 경로가 존재하지 않는다면
    	// 파일이 위치할 경로까지의 디렉터리들을 생성
    	if (!newFile.getParentFile().exists())
    	{
    		newFile.getParentFile().mkdirs();
    	}
    	
    	// 파일에 넣기 위한 Hashtable 객체 생성
    	Hashtable<String, String> h = new Hashtable<String, String>();
    	
    	// Hashtable 객체에 데이터 넣기
    	h.put("key1", "사과");
    	h.put("key2", "수박");
    	
    	// 파일을 내보내기 위한 스트림 구성
    	FileOutputStream fos = new FileOutputStream(newFile);
    	
    	// Object 를 파일에 쓰기 위해 ObjectoutputStream 객체 생성
    	ObjectOutputStream oos = new ObjectOutputStream(fos);
    	
    	// ObjectOutputStream 을 이용해서 파일에 Object 를 기록
    	oos.writeObject(h);
    	
    	// 리소스 반납
    	oos.close();
    	fos.close();
    	
    %>

    • ObjectRead.jsp
    <%@page import="java.util.Enumeration"%>
    <%@page import="java.util.Hashtable"%>
    <%@page import="java.io.ObjectInputStream"%>
    <%@page import="java.io.FileInputStream"%>
    <%@page import="java.io.File"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	/* ObjectRead.jsp */
    	
    	// 어플리케이션 루트 확인
    	String appRoot = "/";
    	appRoot = pageContext.getServletContext().getRealPath(appRoot);
    	
    	// 파일을 읽기 위해 객체 생성
    	File newFile = new File(appRoot,"objData/data.ser");
    	
    	// 파일 존재하는지의 여부 확인
    	if(newFile.exists())
    	{
    		// File 을 읽어오기 위한 FileInputStream 구성
    		FileInputStream fis = new FileInputStream(newFile);
    		
    		// File 에서 Object 를 읽어오기 위해 ObjectInputStream 객체 생성
    		ObjectInputStream ois = new ObjectInputStream(fis);
    		
    		// ObjectOutputStream 을 이요해서 파일에 Object 를 기록
    		// 읽어온 Object 를 원래의 타입으로 캐스팅
    		Hashtable h = (Hashtable)ois.readObject();
    		
    		// 리소스 반납
    		ois.close();
    		fis.close();
    		
    		Enumeration e = h.keys();
    		while (e.hasMoreElements())
    		{
    			String key = (String)e.nextElement();
    			String value = (String)h.get(key);
    			%>
    			
    			<%=key %>의 값은 <%=value %> 입니다. <br>
    			
    			<%
    		}
    	}
    	else
    	{
    		out.println("해당 파일이 없습니다");
    	}
    %>

    fileSystemApp04
    - 파일 업로드 / 전송 : 일반적인 request 로 수신 불가능함 확인
    - lib 에 cos.jar 추가
    • Send.jsp
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Send.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>파일시스템 및 파일업로드</h1>
    	<hr />
    </div>
    
    <div>
    	<!--
    		『enctype="multipart/form-data"』 : 파일을 물리적으로 업로드하기 위한 필수 속성
    		『method="post"』                 : 파일을 물리적으로 업로드하기 위한 요청 및 전송 방식
    	-->
    	<form action="Receive.jsp" method="post" enctype="multipart/form-data">
    		
    		이름 : <input type="text" name="name" class="txt"/><br>
    		
    		<!-- 파일 업로드 대화창 구성 -->
    		파일 : <input type="file" name="upload"/><br>
    		
    		<button type="submit" class="btn">전송</button>
    	</form>
    </div>
    
    </body>
    </html>

    • Receive.jsp
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	/* 파일업로드 시 request 로 name 받아올 수 없는 것 확인 */
    	String name = request.getParameter("name");
    	String upload = request.getParameter("upload");
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Receive.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	이름 : <%=name %> <br>
    	파일 : <%=upload %> <br>
    </div>
    
    	<!--
    		『Send.jsp』의 form 엘리먼트 enctype 속성을
    		『enctype="multipart/form-data"』 와 같이 구성할 경우
    		form 의 내용을 바이너리 값의 형태로 전송한다는 의미이며,
    		이와 같이 전송할 경우... 수신된 데이터는 아래와 같이 확인된다.
    		
    		이름 : null
    		파일 : null
    		
    		==> 즉, 바이너리 값을 getParameter() 를 통해 수신할 수 없다는 의미이다.
    	-->
    
    </body>
    </html>

    fileSystemApp05
    - 파일 업로드 / 전송 : 
    • UploadForm.jsp
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>UploadForm.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>파일 입력 폼</h1>
    	<hr />
    </div>
    
    <div>
    	<form action="Receive.jsp" method="post" enctype="multipart/form-data">
    	
    		file : <input type="file" name="file" size="50"/><br>
    	
    		text : <input type="text" name="file" size="50"/><br>
    	
    		<input type="submit" value="upload" />
    		
    	</form>
    </div>
    
    </body>
    </html>

    • Receive.jsp
    <%@page import="java.io.DataInputStream"%>
    <%@page import="java.util.Enumeration"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	/* Receive.jsp */
    	
    	String contenType = request.getContentType();
    	//-- request의 컨텐츠 타입 얻어옴	
    
    	Enumeration e = request.getHeaderNames();
    	//-- 헤더 안의 이름들을 꺼내려고 하는 것
    	
    	out.println("[[브라우저로부터 날아오는 헤더 정보들]]<br>");
    	
    	while(e.hasMoreElements())	//-- 헤더 이름으로부터 하나씩 꺼내오기
    	{
    		String key = (String)e.nextElement();	//-- key(이름) 을 꺼내고
    		String value = request.getHeader(key);	//-- key 에 연결된 값 꺼내오기
    		
    		out.println(key + " " + value + "<br>");
    	}
    	
    	out.println("[[request 로 넘어오는 데이터들]]<br>");
    	
    	DataInputStream dis = new DataInputStream(request.getInputStream());
    	String line = null;
    	while( (line=dis.readLine()) != null)
    	{
    		//out.println(new String(line.getBytes("UTF-8"), "UTF-8") + "<br>");
    		out.println(new String(line.getBytes("ISO-8859-1"), "UTF-8") + "<br>");
    	}
    		
    %>
    728x90
Designed by planet-si