2020년 11월 13일
업데이트:
IO
IO(입출력)
컴퓨터 내부 또는 외부 장치와 프로그램 간의 데이터를 주고 받는 것이다.
Stream(스트림)
입출력 장치에서 데이터를 읽고 쓰기 위해서 자바에서 제공하는 클래스이다. 모든 스트림은 단방향이며 각각의 장치마다 연결할 수 있는 스트림 존재한다. 하나의 스트림으로 입출력을 동시에 수행할 수 없으므로 동시에 수행하려면 2개의 스트림 필요하다.
// IORun.java
package com.kh.io.run;
import com.kh.io.model.service.FileService;
import com.kh.io.view.IOView;
public class IORun {
public static void main (String[] args) {
FileService fs = new FileService();
new IOView().displayMain();
}
}
// IOView.java
package com.kh.io.view;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
import com.kh.io.model.service.ByteService;
import com.kh.io.model.service.CharService;
public class IOView {
private Scanner sc = new Scanner(System.in);
private ByteService bService = new ByteService();
private CharService cService = new CharService();
public void displayMain() {
int sel = 0;
do {
try {
System.out.println("=== 입출력 메뉴 ===");
System.out.println("1. BYTE 기반 파일 작성(출력)");
System.out.println("2. BYTE 기반 파일 열기(입력)");
System.out.println("3. 문자 기반 파일 작성(출력)");
System.out.println("4. 문자 기반 파일 열기(입력)");
System.out.println("5. 파일 복사(입력 + 출력)");
System.out.println("0. 종료");
System.out.println("메뉴선택 >>");
sel = sc.nextInt();
sc.nextLine(); // 이후 동작에서 문자를 입력 받을 수 있기 때문에 개행문자 미리 제거
switch(sel) {
case 1: byteFileSave(); break;
case 2: byteFileOpen(); break;
case 3: charFileSave(); break;
case 4: charFileOpen(); break;
case 5: break;
case 0: System.out.println("프로그램 종료"); break;
default: System.out.println("잘못 입력함.");
}
}catch(InputMismatchException e) {
System.out.println("정수만 입력해주세요.");
sel = -1; // sel이 0으로 유지돼서 종료되는걸 방지
sc.nextLine(); // 입력 버퍼에 남아있는 잘못 입력한 문자열을 제거
}catch(Exception e) {
e.printStackTrace(); // 모든 예외처리 준비 완료
}
}while(sel !=0);
}
바이트 기반 출력/입력
// IOView.java
// 바이트 기반 출력
private void byteFileSave() throws FileNotFoundException {
System.out.println("--- 바이트 기반 파일 입력 ---");
System.out.print("새로 생성할 파일 명 :");
String fileName = sc.nextLine(); //파일 명 입력 받음
// 입력되는 모든 내용을 합쳐서 저장
StringBuffer content = new StringBuffer(); // 메모리 용량 아끼기 위해
// 입력되는 내용 한 줄을 임시 저장할 변수
String input = null;
System.out.println("-----파일 내용 입력(exit 입력 시 입력 종료)-----");
while(true) {
input = sc.nextLine();
if(input.equals("exit")) break; //입력받은 문자열이 exit인 경우 반복문을 종료함.
// StringBuffer에 입력받은 내용 + 개행문자를 추가
content.append(input + "\n");
}
// 입력받은 파일명과 내용을 ByteService에 있는
// byteFileSave() 메소드에 전달하여 결과를 반환 받기.
int result = bService.byteFileSave(fileName, content.toString());
if(result == 1) {
System.out.println(fileName + ".txt 파일 저장 성공");
} else {
System.out.println(fileName + ".txt 파일 저장 실패");
}
}
// 바이트 기반 파일 입력
private void byteFileOpen() throws FileNotFoundException {
System.out.println("---바이트 기반 파일 입력---");
System.out.print("읽어올 파일 경로 입력 : ");
String path = sc.nextLine(); // ex)byte/test.txt 바이트폴더에있는 test.txt를 읽어와라
String content = bService.byteFileOpen(path);
if(content == null) { // 읽어온 내용이 없는 경우 == 파일 열기 실패
System.out.println(path + "파일 열기 실패");
}else {
System.out.println(path + "파일 열기 성공");
System.out.println("-------------------------");
System.out.println(content);
System.out.println("-------------------------");
}
}
// ByteService.java
package com.kh.io.model.service;
import java.io.File;
import java.io.FileNotFoundException;
import com.kh.io.model.dao.ByteDAO;
public class ByteService {
private ByteDAO byteDAO = new ByteDAO();
// 바이트 기반 출력 Service
public int byteFileSave(String fileName, String content) throws FileNotFoundException {
File folder = new File("byte");
if(!folder.exists()) { // byte 폴더가 존재하지 않는 경우
folder.mkdir(); // 폴더 생성
}
int result = byteDAO.byteFileSave(fileName, content, "byte");
return result; // bytoDAO.byteFileSave() 의 수행결과를 그대로 View로 반환.
}
// 바이트 기반 파일 입력 Service
public String byteFileOpen(String path) throws FileNotFoundException {
// Service는 DAO로 전달할 데이터 또는 반환 받은 데이터를 가공하는 역할 (비즈니스 로직)
String content = byteDAO.byteFileOpen(path);
return content;
}
}
// ByteDAO.java
package com.kh.io.model.dao;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteDAO {
// 바이트 기반 스트림 : 1byte 단위로 데이터를 입력 또는 출력하는 스트림
public int byteFileSave(String fileName, String content, String path) throws FileNotFoundException {
int result = 0;
// 프로그램에서 파일로 출력.
// FileOutputStream 사용
// byte폴더 안에 입력받은 파일명.txt 파일을 출력할 스트림 객체 생성
FileOutputStream fOut
= new FileOutputStream(path + "/" + fileName + ".txt" /*, true*/);
// -> path에서 받아온 폴더 아래, 입력받은 fileName 파일 이름으로, txt형식
try {
for(int i=0; i<content.length(); i++) {
// content에 작성된 문자의 개수만큼 반복하며
// 한 글자씩 스트림을 통해 파일로 출력
// 1바이트씩 끊어서 넣음
fOut.write(content.charAt(i));
}
result = 1;
} catch(IOException e) {
e.printStackTrace();
}finally {
try {
if(fOut != null) {
fOut.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result; //실패하면 기본값 0 반환.
}
// 파일에서 프로그램으로 입력하는 모습
// 바이트 기반 스트림
public String byteFileOpen(String path) throws FileNotFoundException {
//읽어올 파일을 저장할 변수
StringBuffer sb = null;
FileInputStream fis = new FileInputStream(path);
// 바이트 기반 스트림의 read() 메소드는
// 파일의 내용을 순차적으로 1바이트씩 읽어옴.
// 더이상 읽어 올 내용이 없다면 -1을 반환한다.
try {
sb = new StringBuffer();
int value =0; // read()를 통해 읽어온 값을 임시 저장할 변수.
while( (value = fis.read()) != -1) {
// while문을 이용해서 read() 메소드가 -1이 나올 때 까지 반복
// 읽어온 값 value를 char형태로 형변환하여
// sb(스트링버퍼)에 누적
sb.append((char)value);
}
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
if(fis != null) fis.close();
}catch(IOException e) {
e.printStackTrace();
}
}
if( sb != null) {
return sb.toString();
}else {
return null;
}
}
}
문자 기반 출력/입력
// IOView.java
// 문자 기반 파일 출력
private void charFileSave() throws IOException {
System.out.println("--- 문자 기반 파일 출력 ---");
System.out.print("새로 생성할 파일 명 :");
String fileName = sc.nextLine();
StringBuffer content = new StringBuffer();
String input = null;
System.out.println("-----파일 내용 입력(exit 입력 시 입력 종료)-----");
while(true) {
input = sc.nextLine();
if(input.equals("exit")) break; //입력받은 문자열이 exit인 경우 반복문을 종료함.
content.append(input + "\n");
}
// 입력받은 파일명과 내용을 charService에 있는
// charFileSave() 메소드에 전달하여 결과를 반환 받기.
int result = cService.charFileSave(fileName, content.toString());
if(result == 1) {
System.out.println(fileName + ".txt 파일 저장 성공");
} else {
System.out.println(fileName + ".txt 파일 저장 실패");
}
}
// 문자 기반 파일 입력
private void charFileOpen() throws FileNotFoundException {
System.out.println("---문자 기반 파일 입력---");
System.out.print("읽어올 파일 경로 입력 : ");
String path = sc.nextLine();
String content = cService.charFileOpen(path);
if(content == null) {
System.out.println(path + "파일 열기 실패");
}else {
System.out.println(path + "파일 열기 성공");
System.out.println("-------------------------");
System.out.println(content);
System.out.println("-------------------------");
}
}
// CharService.java
package com.kh.io.model.service;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import com.kh.io.model.dao.CharDAO;
public class CharService {
private CharDAO charDAO = new CharDAO();
public int charFileSave(String fileName, String content) throws IOException { /
File folder = new File("char"); //폴더이름 char
if(!folder.exists()) {
folder.mkdir();
}
int result = charDAO.charFileSave(fileName, content, "char");
return result;
}
public String charFileOpen(String path) throws FileNotFoundException {
return charDAO.charFileOpen(path);
}
}
// CharDAO
package com.kh.io.model.dao;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharDAO {
// 문자 기반 스트림 : 2byte 문자 단위(유니코드)로 데이터를 입력 또는 출력하는 스트림
// 프로그램 -> 파일로 content 출력
public int charFileSave(String fileName, String content, String path) throws IOException {
int result = 0;
FileWriter fw = new FileWriter(path + "/" + fileName + ".txt");
try {
fw.write(content);
// 문자 기반 스트림은
// 문자만 가지고 있는 데이터를 송수신하는 용도
// 문자 기반 스트림의 write() 메소드는 모든 문자를 순서대로 내보내도록 내부적으로 구현되어 있음.
// 무조건 문자가 들어오니까 알아서 끊어서 받아옴..
result = 1;
}catch(IOException e) {
e.printStackTrace();
} finally {
try {
if(fw!=null) {
fw.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
return result;
}
// 파일에서 프로그램으로 입력하는 것.
public String charFileOpen(String path) throws FileNotFoundException {
StringBuffer sb = null;
FileReader fr = new FileReader(path);
try {
sb = new StringBuffer();
// write와는 다르게
// FileReader 의 read()메소드는 한번에 읽어올 수 없음. 한 글자씩 읽어와야 한다.
// 더이상 읽을 내용이 없다면 -1을 반환한다.
int value = 0;
while((value = fr.read()) != -1) {
sb.append( (char)value ); .
}
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(fr != null) fr.close();
}catch(Exception e) {
e.printStackTrace();
}
}
if( sb != null) {
return sb.toString();
}else {
return null;
}
}
}
공유하기
Twitter Google+ LinkedIn
댓글남기기