국비교육(22-23)

54일차(1)/Spring(13) : 자료실 게시판 만들기, 파일 업로드 기능 구현

서리/Seori 2022. 12. 22. 22:29

54일차(1)/Spring(13) : 자료실 게시판 만들기, 파일 업로드 기능 구현

 

- File 게시판 dao, mapper 작성

- 파일 업로드 기능 구현

 

 

** mapper 에 별칭 부여하기

 

- parameterType="" resultType="" 작성되어 있는 내용이 너무 길다.
- 이 내용을 따로 작성해놓고 불러올 수 있다. 

<!-- 자주 사용하는 type의 별칭을 등록해 놓고 Mapper xml 에서 사용할 수 있다. -->
<typeAliases>
	<typeAlias type="com.sy.spring04.users.dto.UsersDto" alias="usersDto"/>
</typeAliases>

<mapper resource="mapper/FileMapper.xml"/>

 

- configuration에 별칭(alias)를 저장해 놓을 수 있다. (UsersDto)

 

- 그러면 mapper에서 이렇게 별칭으로 자동 완성되도록 뜬다.

 


 

- 홈에 자료실 목록 추가! (list)

 

FileDto

package com.sy.spring04.file.dto;

import org.springframework.web.multipart.MultipartFile;

public class FileDto {
	private int num;
	private String writer;
	private String title;
	//원본 파일명
	private String orgFileName;
	//파일 시스템에 저장된 파일명
	private String saveFileName;
	//파일의 크기 
	private long fileSize;
	private String regdate;
	//페이징 처리를 위한 필드
	private int startRowNum;
	private int endRowNum;
	//파일 업로드 처리를 하기 위한 필드
	private MultipartFile myFile;

	public FileDto () {}

	public FileDto(int num, String writer, String title, String orgFileName, String saveFileName, long fileSize,
			String regdate, int startRowNum, int endRowNum, MultipartFile myFile) {
		super();
		this.num = num;
		this.writer = writer;
		this.title = title;
		this.orgFileName = orgFileName;
		this.saveFileName = saveFileName;
		this.fileSize = fileSize;
		this.regdate = regdate;
		this.startRowNum = startRowNum;
		this.endRowNum = endRowNum;
		this.myFile = myFile;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getOrgFileName() {
		return orgFileName;
	}

	public void setOrgFileName(String orgFileName) {
		this.orgFileName = orgFileName;
	}

	public String getSaveFileName() {
		return saveFileName;
	}

	public void setSaveFileName(String saveFileName) {
		this.saveFileName = saveFileName;
	}

	public long getFileSize() {
		return fileSize;
	}

	public void setFileSize(long fileSize) {
		this.fileSize = fileSize;
	}

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	public int getStartRowNum() {
		return startRowNum;
	}

	public void setStartRowNum(int startRowNum) {
		this.startRowNum = startRowNum;
	}

	public int getEndRowNum() {
		return endRowNum;
	}

	public void setEndRowNum(int endRowNum) {
		this.endRowNum = endRowNum;
	}

	public MultipartFile getMyFile() {
		return myFile;
	}

	public void setMyFile(MultipartFile myFile) {
		this.myFile = myFile;
	}	
	
}

 

FileDao 인터페이스

package com.sy.spring04.file.dao;

import java.util.List;

import com.sy.spring04.file.dto.FileDto;

public interface FileDao {
	   public void insert(FileDto dto);
	   public FileDto getData(int num);
	   public void delete(int num);
	   public List<FileDto> getList(FileDto dto);
	   public int getCount(FileDto dto);	      
	   
}

 

- getList 목록을 리턴하는 메소드

- getList에서 Dto를 넘겨주는 이유는 페이징처리를 위해서!(startRowNum, endRowNum)

그리고 검색기능을 만들 것인데, 검색 키워드도 Dto에 담아서 전달할 예정이다.

 

- getCount는 파일 전체의 개수를 세는 메소드(페이징처리를 위해)

그리고 검색키워드에 맞는 자료가 몇개가 있는지 찾는 작업에 dto를 인자로 받는게 필요하다.

 

 

FileService 인터페이스

package com.sy.spring04.file.service;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.servlet.ModelAndView;

import com.sy.spring04.file.dto.FileDto;

public interface FileService {
	//파일 목록 얻어오기 
	public void getList(HttpServletRequest request);
	//업로드된 파일 저장하기 
	public void saveFile(FileDto dto, ModelAndView mView,
	      HttpServletRequest request);
	//파일하나의 정보 얻어오기 
	public void getFileData(int num, ModelAndView mView);
	//파일 삭제하기
	public void deleteFile(int num, HttpServletRequest request);

}

 

FileMapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="file">
   <insert id="insert" parameterType="fileDto">
      INSERT INTO board_file
      (num, writer, title, orgFileName, saveFileName, fileSize, regdate)
      VALUES(board_file_seq.NEXTVAL, #{writer}, #{title}, 
         #{orgFileName}, #{saveFileName}, #{fileSize}, SYSDATE)
   </insert>
   <select id="getData" parameterType="int" resultType="fileDto">
      SELECT num,writer,title,orgFileName,saveFileName,fileSize,regdate
      FROM board_file
      WHERE num=#{num}
   </select>
   <delete id="delete" parameterType="int">
      DELETE FROM board_file
      WHERE num=#{num}
   </delete>
   <select id="getList" parameterType="fileDto" 
      resultType="fileDto">
      SELECT *
      FROM
         (SELECT result1.*, ROWNUM AS rnum
         FROM
            (SELECT num,writer,title,orgFileName,saveFileName,
               fileSize,regdate
            FROM board_file
            
            <choose>
               <when test="title != null and orgFileName != null">
                  WHERE title LIKE '%'||#{title}||'%' OR orgFileName LIKE '%'||#{orgFileName}||'%'
               </when>
               <when test="title != null">
                  WHERE title LIKE '%'||#{title}||'%'
               </when>
               <when test="writer != null">
                  WHERE writer LIKE '%'||#{writer}||'%'
               </when>
            </choose>
            
            ORDER BY num DESC) result1)
      WHERE rnum BETWEEN #{startRowNum} AND #{endRowNum}
   </select>
   <select id="getCount" parameterType="fileDto" resultType="int">
      SELECT NVL(MAX(ROWNUM), 0)
      FROM board_file
      <choose>
         <when test="title != null and orgFileName != null">
            WHERE title LIKE '%'||#{title}||'%' OR orgFileName LIKE '%'||#{orgFileName}||'%'
         </when>
         <when test="title != null">
            WHERE title LIKE '%'||#{title}||'%'
         </when>
         <when test="writer != null">
            WHERE writer LIKE '%'||#{writer}||'%'
         </when>
      </choose>
   </select>
</mapper>

 

- FileMapper를  Configuration 목록에 등록해주기

 

 

- FileDaoImpl

package com.sy.spring04.file.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.sy.spring04.file.dto.FileDto;

@Repository
public class FileDaoImpl implements FileDao{

	@Autowired
	private SqlSession session;
	
	@Override
	public void insert(FileDto dto) {
		session.insert("file.insert", dto);
		
	}

	@Override
	public FileDto getData(int num) {
		return session.selectOne("file.getData", num);		 
	}

	@Override
	public void delete(int num) {
		session.delete("file.delete", num);
		
	}

	@Override
	public List<FileDto> getList(FileDto dto) {
				
		return session.selectList("file.getList", dto);
	}

	@Override
	public int getCount(FileDto dto) {
		
		return session.selectOne("file.getCount", dto);
	}

}

 

 

mapper - insert

<insert id="insert" parameterType="fileDto">
  INSERT INTO board_file
  (num, writer, title, orgFileName, saveFileName, fileSize, regdate)
  VALUES(board_file_seq.NEXTVAL, #{writer}, #{title}, 
     #{orgFileName}, #{saveFileName}, #{fileSize}, SYSDATE)
</insert>

 

- Dao에서 insert 메소드를 작성하면서 mapper의 name, id, parameterType 생각하기

 

- 1번을 보고 2번을 작성할 수 있으면 된다.

 

- session을 사용해서 가져온 값을 바로 리턴해준다.

- resultType은 FileDto이다.

 

- selectOne의 경우, return Type이 곧 resultType이다.

 

- 여기서 parameter는 오직 하나. select된 row 하나의 정보를 dto에 담아달라는 의미

- 사용자가 one으로 사용하든 list로 사용하든 상관없다.

 

 

- SelectList로 작성하게 되면 이렇게 된다.

- 리턴타입 : List / resultType: FileDto(제너릭타입<>)

 

- 똑같은 sql문의 select문을 사용하더라도

selectList로 사용하느냐 selectOne으로 사용하느냐에 따라 리턴 타입이 달라진다. 기억하기!!

 

 

- getList

<select id="getList" parameterType="fileDto" 
  resultType="fileDto">
	SELECT *
	FROM
    	(SELECT result1.*, ROWNUM AS rnum
    	FROM
        	(SELECT num,writer,title,orgFileName,saveFileName,
           		fileSize,regdate
        	FROM board_file

        	ORDER BY num DESC) result1)
	WHERE rnum BETWEEN #{startRowNum} AND #{endRowNum}
</select>

 

- getList. 페이징 처리에 필요한 sql문 (서브쿼리 사용)

1) 정렬

2) 행 번호 부여

3) 원하는 행 추려내기

 

- getCount의 경우 숫자를 하나 select하는 것이므로 resultType은 int이다.

 

- 나중에 검색기능을 만들고 검색 키워드가 있는 경우

  sql의 저 위치에 WHERE절을 추가할 예정! (동적 sql문)

 

- configuration.xml에 mapper와 alias 등록

 

- 등록하고 나면 mapper에서 이렇게 일괄 수정할 수 있다.(ctrl+F)

 

 

FileServiceImpl

package com.sy.spring04.file.service;

import java.io.File;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.sy.spring04.file.dao.FileDao;
import com.sy.spring04.file.dto.FileDto;

@Service
public class FileServiceImpl implements FileService{

	@Autowired
	private FileDao dao;
	
	@Override
	public void getList(HttpServletRequest request) {
	   //한 페이지에 몇개씩 표시할 것인지
	   final int PAGE_ROW_COUNT=5;
	   //하단 페이지를 몇개씩 표시할 것인지
	   final int PAGE_DISPLAY_COUNT=5;

	   //보여줄 페이지의 번호를 일단 1이라고 초기값 지정
	   int pageNum=1;

	   //페이지 번호가 파라미터로 전달되는지 읽어와 본다.
	   String strPageNum=request.getParameter("pageNum");
	   //만일 페이지 번호가 파라미터로 넘어 온다면
	   if(strPageNum != null){
	      //숫자로 바꿔서 보여줄 페이지 번호로 지정한다.
	      pageNum=Integer.parseInt(strPageNum);
	   }   
	   
	   //보여줄 페이지의 시작 ROWNUM
	   int startRowNum=1+(pageNum-1)*PAGE_ROW_COUNT;
	   //보여줄 페이지의 끝 ROWNUM
	   int endRowNum=pageNum*PAGE_ROW_COUNT;
	   
	   //하단 시작 페이지 번호 
	   int startPageNum = 1 + ((pageNum-1)/PAGE_DISPLAY_COUNT)*PAGE_DISPLAY_COUNT;
	   //하단 끝 페이지 번호
	   int endPageNum=startPageNum+PAGE_DISPLAY_COUNT-1;
	   //전체 글의 갯수
	   int totalRow=dao.getCount( new FileDto() );
	   //전체 페이지의 갯수 구하기
	   int totalPageCount=(int)Math.ceil(totalRow/(double)PAGE_ROW_COUNT);
	   //끝 페이지 번호가 이미 전체 페이지 갯수보다 크게 계산되었다면 잘못된 값이다.
	   if(endPageNum > totalPageCount){
	      endPageNum=totalPageCount; //보정해 준다. 
	   }
	   
	   //FileDto 객체를 생성해서 
	   FileDto dto=new FileDto();
	   //위에서 계산된 startRowNum , endRowNum 을 담아서 
	   dto.setStartRowNum(startRowNum);
	   dto.setEndRowNum(endRowNum);
	   //파일 목록을 select 해 온다. 
	   List<FileDto> list=dao.getList(dto);	
	   //view page 에 전달하기 위해 request scope에 담는다.
	   request.setAttribute("list", list);
	   request.setAttribute("pageNum", pageNum);
	   request.setAttribute("startPageNum", startPageNum);
	   request.setAttribute("endPageNum", endPageNum);
	   request.setAttribute("totalPageCount", totalPageCount);	   
	}

	@Override
	public void saveFile(FileDto dto, ModelAndView mView, HttpServletRequest request) {
	      //업로드된 파일의 정보를 가지고 있는 MultipartFile 객체의 참조값 얻어오기 
	      MultipartFile myFile=dto.getMyFile();
	      //원본 파일명
	      String orgFileName=myFile.getOriginalFilename();
	      //파일의 크기
	      long fileSize=myFile.getSize();
	      
	      // webapp/resources/upload 폴더 까지의 실제 경로(서버의 파일시스템 상에서의 경로)
	      String realPath=request.getServletContext().getRealPath("/resources/upload");
	      //저장할 파일의 상세 경로
	      String filePath=realPath+File.separator;
	      //디렉토리를 만들 파일 객체 생성
	      File upload=new File(filePath);
	      if(!upload.exists()) {//만일 디렉토리가 존재하지 않으면 
	         upload.mkdir(); //만들어 준다.
	      }
	      //저장할 파일 명을 구성한다.
	      String saveFileName=
	            System.currentTimeMillis()+orgFileName;
	      try {
	         //upload 폴더에 파일을 저장한다.
	         myFile.transferTo(new File(filePath+saveFileName));
	         System.out.println(filePath+saveFileName);
	      }catch(Exception e) {
	         e.printStackTrace();
	      }
	      //dto 에 업로드된 파일의 정보를 담는다.
	      String id=(String)request.getSession().getAttribute("id");
	      dto.setWriter(id); //세션에서 읽어낸 파일 업로더의 아이디 
	      dto.setOrgFileName(orgFileName);
	      dto.setSaveFileName(saveFileName);
	      dto.setFileSize(fileSize);
	      //fileDao 를 이용해서 DB 에 저장하기
	      dao.insert(dto);
	      //view 페이지에서 사용할 모델 담기 
	      mView.addObject("dto", dto);		
	}

	@Override
	public void getFileData(int num, ModelAndView mView) {
		//다운로드할 파일의 정보를 얻어와서
		FileDto dto=dao.getData(num);
		//ModelAndView 객체에 담아준다
		mView.addObject("dto", dto);		
	}

	@Override
	public void deleteFile(int num, HttpServletRequest request) {
		//삭제할 파일의 정보를 얻어오기
		FileDto dto=dao.getData(num);
		//파일 시스템에서 삭제(upload 폴더에서 해당파일을 삭제)
		String saveFileName=dto.getSaveFileName();
		String path=request.getServletContext().getRealPath("/resources/upload")
				+File.separator+saveFileName;
		//경로를 사용해서 파일객체를 생성해서
		new File(path).delete();
		//DB에서 파일 정보 삭제
		dao.delete(num);		
	}

}

 

- 인터페이스를 구현해주고, 

 @Service 추가, FileDao @Autowired 해주기

 

 

FileController

package com.sy.spring04.file.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sy.spring04.file.dto.FileDto;
import com.sy.spring04.file.service.FileService;

@Controller
public class FileController {

	@Autowired
	private FileService service;
	
	@RequestMapping("/file/list")
	public String list(HttpServletRequest request) {
		service.getList(request);
		
		return "file/list";
	}
	
	@RequestMapping("/file/upload_form")
	public String uploadForm() {
		return "file/upload_form";
	}
	
	@RequestMapping("/file/upload")
	public ModelAndView upload(FileDto dto, ModelAndView mView, HttpServletRequest request) {
		service.saveFile(dto, mView, request);
		mView.setViewName("file/upload");
		return mView;		
	}
	
}

 

- @Controller 추가 / service @Autowired

 

- getList 는 request를 전달해주는 구조. 전달해주면 파일목록을 setAttribute로 받아주면된다.

- 왜 request를 넘겨주었냐면.. 예전 코드를 최대한 재활용하기 위해서 ㅎㅎ

 

- 이전에 List 에서 작성했던 java 코드는 이제 서비스 메소드 안에서 처리할 수 있도록 작성해야한다.

- 이 정보를 처리하기 위해서는 request 객체가 필요하다.

 

- dao는 그냥 존재하므로 getInstance()를 사용할 필요가 없다. 그냥 dao로 수정해주면 된다.

 

 

List<FileDto> list=dao.getList(dto);

request.setAttribute("list", list); ← 이 코드가 추가되었다.

- 이전 jsp에서는 startRowNum, endRowNum 를 select해와서 바로 사용했는데

  spring MVC 에서는 일단 request영역에 담고 view페이지로 포워드이동해서 응답한다.

 

- list안에는 FileDto 타입이 담겨있다. 필드명을 사용해 가져오기!

 

- c:forEach문으로 수정해주기

- 삭제 버튼은 작성자와 로그인한 사람이 같을때만 조건부로 출력해준다.

 

- pageNum, StartPageNum, endPageNum, TotalpageCount

 4개의 정보는 req 영역에 담아서 가져와야한다. (service에서 추가해줌)

 

- 서비스에서 request 에 넣어서 담아준다.

- dto에 한번에 담아서 전달할 수도 있다.

 

- startPageNum이 1이 아니면 prev 링크가 나오도록 c:if로 작성

 

- 변수명을 i 로 지정해서 1씩 증가하는 forEach문 작성

 

- JSTL과 EL로 수정해주기

 


 

- interceptor 추가

<interceptors>
    <interceptor>			
        <mapping path="/users/*"/>
        <mapping path="/file/*"/>
        <exclude-mapping path="/users/signup_form"/>
        <exclude-mapping path="/users/signup"/>
        <exclude-mapping path="/users/loginform"/>
        <exclude-mapping path="/users/login"/>
        <exclude-mapping path="/file/list"/>
        <beans:ref bean="loginInterceptor"/>
    </interceptor>
</interceptors>

- file 하위 페이지 추가하기

- interceptor bean 하나를 여러 interceptor 에 적용가능!

 


 

upload_form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/views/file/upload_form.jsp</title>
</head>
<body>
   <div class="container">
      <h3>파일 업로드 폼 입니다.</h3>
      <!-- 
         파일 업로드 폼 작성법
         1. method="post"
         2. enctype="multipart/form-data"
         3. <input type="file" />
         - enctype="multipart/form-data" 가 설정된 폼을 전송하면
           폼전송된 내용을 추출할때 HttpServletRequest 객체로 추출을 할수 없다
          MultipartRequest 객체를 이용해서 추출해야 한다. 
       -->
      <form action="upload" method="post" enctype="multipart/form-data">
         <div>
            <label for="title">제목</label>
            <input type="text" name="title" id="title"/>
         </div>
         <div>
            <label for="myFile">첨부파일</label>
            <input type="file" name="myFile" id="myFile"/>
         </div>
         <button type="submit">업로드</button>
      </form>
   </div>
</body>
</html>

 

- 제목, 첨부파일만 넣도록 되어있음

- input요소에 지정한 name값 기억! fileDto로 받을 수 있다.

- 단 받으려면 FileDto에 title, myFile이라는 필드가 있어야한다.

 

- Dto에 필드가 준비되어 있다.

- file의 타입이 반드시 MultipartFile이어야 한다!!

 

- 이곳에 업로드하면 DTO 에 파일 이름(title)과 업로드된 파일의 정보(myFile)가 담긴다.

 

- dto에 담아서 이 메소드에서 사용한다.

 

- 서비스 메소드에 request가 필요하므로 메소드의 인자로 추가해주기

 

 

- Service의 saveFile 메소드 작성

@Override
public void saveFile(FileDto dto, ModelAndView mView, HttpServletRequest request) {
      //업로드된 파일의 정보를 가지고 있는 MultipartFile 객체의 참조값 얻어오기 
      MultipartFile myFile=dto.getMyFile();
      //원본 파일명
      String orgFileName=myFile.getOriginalFilename();
      //파일의 크기
      long fileSize=myFile.getSize();

      // webapp/resources/upload 폴더 까지의 실제 경로(서버의 파일시스템 상에서의 경로)
      String realPath=request.getServletContext().getRealPath("/resources/upload");
      //저장할 파일의 상세 경로
      String filePath=realPath+File.separator;
      //디렉토리를 만들 파일 객체 생성
      File upload=new File(filePath);
      if(!upload.exists()) {//만일 디렉토리가 존재하지 않으면 
         upload.mkdir(); //만들어 준다.
      }
      //저장할 파일 명을 구성한다.
      String saveFileName=
            System.currentTimeMillis()+orgFileName;
      try {
         //upload 폴더에 파일을 저장한다.
         myFile.transferTo(new File(filePath+saveFileName));
         System.out.println(filePath+saveFileName);
      }catch(Exception e) {
         e.printStackTrace();
      }
      //dto 에 업로드된 파일의 정보를 담는다.
      String id=(String)request.getSession().getAttribute("id");
      dto.setWriter(id); //세션에서 읽어낸 파일 업로더의 아이디 
      dto.setOrgFileName(orgFileName);
      dto.setSaveFileName(saveFileName);
      dto.setFileSize(fileSize);
      //fileDao 를 이용해서 DB 에 저장하기
      dao.insert(dto);
      //view 페이지에서 사용할 모델 담기 
      mView.addObject("dto", dto);		
}

 

- 정확한 경로에 어떤 파일명으로 저장할지 정해야 한다.

- 파일 객체를 생성해서 원하는 파일명을 구성하는 것이 제일 중요!

 

 

- 업로드 폴더까지의 절대경로는 메소드로 얻어낼 수 있다.(getRealPath)

- 나머지 파일구분자(seperator)는 파일 객체의 필드로 얻어낼 수 있다.

- 이것들을 사용해서 파일객체를 저장할 정보를 만들어낸다 → 만들어진 경로를 transferTo에 담아줌

 

 

upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/views/file/upload.jsp</title>
</head>
<body>
	<div class="container">
		<h3>Alert</h3>
		<p>
			<strong>${dto.orgFileName }</strong> 파일이 업로드 되었습니다.
			<a href="${pageContext.request.contextPath}/file/list">확인</a>
		</p>
	</div>
</body>
</html>

 

 

 

- 파일을 업로드하면 콘솔창에 이렇게 파일이 업로드된 경로가 나타난다.

 

- 시스템상의 어떤 경로에 저장되는지를 알아내는 메소드가 getRealPath() 이다.

  이 메소드를 사용해서만 얻어낼 수 있다.

 

 

- 업로드폴더 뒤에 있는 파일구분자( \ )는 File.seperator 를 사용해서 얻어낸 것이다.

- \ 으로 직접 작성해서 넣어버리면 리눅스에서는 쓸 수 없다.

- File.separator 라고 입력하면 시스템에서 알아서 윈도우에서는 \ 를, 리눅스에서는 / 를 반환해준다.

 

- currentTimeMillis() 가 임의의 숫자를 넣어주었고, 뒤에 orgFileName 을 붙여서 파일명이 완성되었다.

- 각각의 코드가 무엇을 가리키는지 알고, 필요에 따라 수정해서 사용할 수 있으면 된다.

 

 

- new File( ) 괄호안에 에 이 경로 문자열을 넘겨준다

- 최종적으로는 이 파일을 transferTo() 에 넘겨줄 수 있으면 된다.