반응형

 

Byte Array IO

 

 

  • 바이트 배열 복사

1. 직접 복사하기

package kr.or.ddit.basic;

import java.util.Arrays;

public class T03ByteArrayIOTest {
	public static void main(String[] args) {
		
		byte[] inSrc = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 바이트 배열
		byte[] outSrc = null;
		
		
		// 방법 1. 직접 복사하기
		outSrc = new byte[inSrc.length];
		
		for(int i=0; i<inSrc.length; i++) {
			outSrc[i] = inSrc[i];
		}
		
		System.out.println("직접 복사 후 outSrc => " + Arrays.toString(outSrc));
	}
}

 

결과 화면1

 

 

 

2. arraycopy를 이용한 배열 복사

package kr.or.ddit.basic;

import java.util.Arrays;

public class T03ByteArrayIOTest {
	public static void main(String[] args) {
		
		byte[] inSrc = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 바이트 배열
		byte[] outSrc = null;
		
		// 방법 2. arraycopy를 이용한 배열 복사하기
		outSrc = new byte[inSrc.length];
		
		// inSrc의 0번째부터 복사하며 outSrc의 0번째부터 복사한 값을 inSrc의 길이만큼 넣음
		System.arraycopy(inSrc, 0, outSrc, 0, inSrc.length);
		System.out.println("직접 복사 후 outSrc => " + Arrays.toString(outSrc));
	}
}

 

결과 화면2

 

 

 

3. 스트림 객체 생성하기 (스트림 클래스 이용)

 

스트림 객체는 input용(데이터를 가져올때)과 output용(데이터를 출력할때)이 존재함

 

 

  • 사용법
사용법
ByteArrayInputStream 바이트 배열에 데이터를 입출력하는데 사용되는 스트림
ByteArrayOutputStream
read() byte단위로 데이터를 읽어와 int형으로 반환
더 이상 읽을 데이터가 없으면 -1
write() 데이터 출력 (System.out.print 처럼 출력하는 것이 아님)
close()
파일 읽기 종료
toByteArray() 출력된 스트림 데이터 배열로 가져옴
toString() 객체가 가지고 있는 정보나 값들을 문자열로 만들어 리턴

 

 

package kr.or.ddit.basic;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;

public class T03ByteArrayIOTest {
	public static void main(String[] args) {
		
		byte[] inSrc = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 바이트 배열
		byte[] outSrc = null;
		
		// 스트림 객체 생성하기
		ByteArrayInputStream bais = new ByteArrayInputStream(inSrc);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		int data = 0; // 읽어온 바이트 데이터를 저장하기 위한 변수
		
		// read() 메서드 => byte단위로 데이터를 읽어와 int형으로 반환한다.
		// 				   더 이상 읽을 데이터가 없으면 -1을 반환한다.
		while((data = bais.read()) != -1) {
			baos.write(data); // 출력하기
		}
		
		// 출력된 스트림 데이터를 배열로 가져오기
		outSrc = baos.toByteArray();
		
		System.out.println("inSrc => " + Arrays.toString(inSrc));
		System.out.println("outSrc => " + Arrays.toString(outSrc));
	}
}

 

결과 화면3

 

 

package kr.or.ddit.basic;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class T04ByteArrayIOTest {
	public static void main(String[] args) throws IOException {
		
		byte[] inSrc = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 바이트 배열
		byte[] outSrc = null;
		
		byte[] temp = new byte[4]; // 데이터 읽을 때 사용할 버퍼용 배열
		
		// 스트림 객체 생성하기
		ByteArrayInputStream bais = new ByteArrayInputStream(inSrc);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		int readBytes = 0; // 읽어온 바이트 개수를 저장하기 위한 변수
		
		// read() 메서드 => byte단위로 데이터를 읽어와 int형으로 반환한다.
		// 				   더 이상 읽을 데이터가 없으면 -1을 반환한다.
		while((readBytes = bais.read(temp)) != -1) {
			// 버퍼 쓰레기가 존재하므로 write 시 번째를 지정해줘야 함
			System.out.println("temp => " + Arrays.toString(temp));
            
//			System.out.println(readBytes); // 4, 4, 2
			baos.write(temp, 0, readBytes); // 출력하기
			// 0번째부터 readBytes번째 까지 복사함
		}
		
		// 출력된 스트림 데이터를 배열로 가져오기
		outSrc = baos.toByteArray();
		
		System.out.println("inSrc => " + Arrays.toString(inSrc));
		System.out.println("outSrc => " + Arrays.toString(outSrc));
	}
}

 

결과 화면4 : write(temp, 0, readBytes)을 지정하지 않을 시 6, 7이 추가로 출력됨

 

 

 

File Stream

 

 

package kr.or.ddit.basic;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * 파일 읽기 예제
 */
public class T05FileStreamTest {
	public static void main(String[] args) {
		
		FileInputStream fis = null;
		
		try {
			// 둘 다 같은 방식
			fis = new FileInputStream("d:/D_Other/test2.txt");
//			fis = new FileInputStream(new File("d:/D_Other/test2.txt"));
			
			int data = 0;
			
			while((data = fis.read()) != -1) {
				// 읽어온 데이터 콘솔에 출력하기
				System.out.print((char)data);
			}
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면5-1 : test2.txt 파일이 없을 시 위의 오류가 뜸

 

test2. txt

 

결과 화면5-2 : 한글은 char로 읽어올 수 없음, 1바이트로 읽어올 수 없기에 불가능

 

 

 

  • 파일 저장 (FileOutputStream)
package kr.or.ddit.basic;

import java.io.FileOutputStream;
import java.io.IOException;

public class T06FileStreamTest {
	public static void main(String[] args) {
		
		// 파일 저장용 스트림 객체 생성하기
		FileOutputStream fos = null;
		
		try {
			fos = new FileOutputStream("d:/D_Other/out.txt");
			
			for(char ch='a'; ch<='z'; ch++) {
				fos.write(ch);
			}
			
			System.out.println("파일 저장 완료....");
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면6

 

파일이 저장됨

 

메모장 안 파일 확인

 

 

 

  • 파일 읽기 (FileInputStream)
package kr.or.ddit.basic;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class T06FileStreamTest {
	public static void main(String[] args) {
		FileInputStream fis = null;
		
		try {
			fis = new FileInputStream("d:/D_Other/out.txt");
			
			int data = 0;
			while ((data = fis.read()) != -1) {
				System.out.print((char) data);
			}
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면7

 

 

 

입력한 내용 그대로 저장

 

InputStreamReader : 바이트 기반 스트림을 문자 기반 스트림으로 변환해주는 보조 스트림

 

package kr.or.ddit.basic;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class T07FileWriterTest {
	public static void main(String[] args) {
		/*
		 * 사용자가 입력한 내용을 그대로 파일로 저장하기
		 * 
		 * InputStreamReader => 바이트 기반 스트림을 문자기반 스트림으로 변환해주는 보조 스트림
		 */
		
		InputStreamReader isr = new InputStreamReader(System.in);
		
		FileWriter fw = null; // 파일 출력용 문자기반 스트림
		
		try {
			fw = new FileWriter("d:/D_Other/testChar.txt");
			
			System.out.println("아무거나 입력하세요.");
			int data = 0;
			
			// 콘솔에서 입력할 때 입력의 끝 표시는 Ctrl + z 키를 누르면 됨
			while( (data = isr.read()) != -1 ) {
				fw.write(data); // 콘솔에서 입력받은 값을 파일에 출력하기
			}
			
			System.out.println("출력 작업 끝...");
			
			isr.close();
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면8

 

메모장 안 파일 확인

 

 

 

문자 기반 스트림

 

FileReader : 문자기반 스트림으로, 파일 내용을 읽는다.

 

package kr.or.ddit.basic;

import java.io.FileReader;
import java.io.IOException;

public class T08FileReaderTest {
	public static void main(String[] args) {
		// 문자기반 스트림을 이용한 파일 내용 읽기
		FileReader fr = null;
		
		try {
			fr = new FileReader("d:/D_Other/testChar.txt");
			
			int data = 0;
			
			while((data = fr.read()) != -1) {
				System.out.print(data + "@");
			}
			
			System.out.println("출력 끝...");
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면9 : int형으로 출력했을 때

 

 

package kr.or.ddit.basic;

import java.io.FileReader;
import java.io.IOException;

public class T08FileReaderTest {
	public static void main(String[] args) {
		// 문자기반 스트림을 이용한 파일 내용 읽기
		FileReader fr = null;
		
		try {
			fr = new FileReader("d:/D_Other/testChar.txt");
			
			int data = 0;
			
			while((data = fr.read()) != -1) {
				System.out.print((char)data + "@");
			}
			
			System.out.println("출력 끝...");
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면10 : 타입 변환한 값 출력

 

 

 

정리

 

  • 바이트 기반 스트림 / 문자 기반 스트림
바이트 기반 스트림 문자 기반 스트림
입력 스트림 출력 스트림 입력 스트림 출력 스트림
FileInputStream FileOutputStream FileReader FileWriter
ByteArrayInputStream ByteArrayOutputStream    

 

 

 

  • 보조 스트림
사용법
InputStreamReader
InputStreamReader (바이트 기반 스트림 객체, 인코딩 방식)
바이트 기반 스트림을 문자기반 스트림으로 변환
파일 인코딩 정보 이용하여 파일 읽기
OutputStreamWriter
OutputStreamWriter(문자 기반 스트림 객체, 인코딩 방식)
문자기반 스트림을 바이트 기반 스트림으로 변환
파일 인코딩 정보 이용하여 파일 읽기
BufferedOutputStream 버퍼 스트림 (바이트 기반 스트림)
byte단위로 파일을 기록 할때 사용
BufferedReader 버퍼 스트림 (문자 기반 스트림)
한 문장 단위로 파일을 기록할 때 사용
DataInputStream 기본 타입 입력
DataOutputStream 기본 타입 출력
PrintStream 프린터 기능
모든 타입의 데이터를 출력
PrintWriter 프린터 기능
모든 타입의 데이터를 출력
=> PrintStream 보다 기능이 좋음
ObjectInputStream
byte 를 Object 또는 Data 형태로 데이터 변환
ObjectOutputStream
Object 또는 Data를 byte 형태로 데이터 변환

 

 

 

인코딩 방식

 

한글 인코딩 방식은 크게 UTF-8 과 EUC-KR 방식 두가지

원래 한글 윈도우는 CP949방식을 사용했는데, 윈도우를 개발한 마이크로소프트에서 EUC-KR 방식에서 
확장하였기 때문에 MS949라고도 부른다.

 

한글윈도우의 메모장에서 말하는 ANSI인코딩이란 CP949(Code Page 949)를 의미한다.
- CP949(MS949) => 한글 윈도우의 한글 인코딩 방식(ANSI계열)
- UTF-8 => 유니코드 UTF-8 인코딩 방식
- US-ASCII => 영문 전용 인코딩 방식

=> ASCII 코드는 영어를 표기하기 위해 만든 코드로 규격 자체에 한글이 없었다가 나중에 여기에 한글이 포함되면서 EUC-KR, CP949 등의 인코딩 방식이 추가되었음.


참고)
ASCII => extended ASCII(ISO9959-1) => 조합형, 완성형(KSC5601) => 윈도우 계열: CP949  |  유닉스 계열: EUC-KR => ANSI계열 => EUC-KR
=> 유니코드(UTF-8)

 

 

InputStreamReader(바이트기반 스트림 객체, 인코딩 방식) : 파일 인코딩 정보 이용하여 파일 읽기

 

package kr.or.ddit.basic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class T09FileEncodingTest {
	/*
	 * 한글 인코딩 방식에 대하여...
	 * 
	 * 한글 인코딩 방식은 크게 UTF-8 과 EUC-KR 방식 두가지로 나누어 볼 수 있다.
	 * 원래 한글 윈도우는 CP949방식을 사용했는데, 윈도우를 개발한 마이크로소프트에서 EUC-KR 방식에서 
	 * 확장하였기 때문에 MS949라고도 부른다.
	 * 한글윈도우의 메모장에서 말하는 ANSI인코딩이란 CP949(Code Page 949)를 의미한다.
	 * - CP949(MS949) => 한글 윈도우의 한글 인코딩 방식(ANSI계열)
	 * - UTF-8 => 유니코드 UTF-8 인코딩 방식
	 * - US-ASCII => 영문 전용 인코딩 방식
	 * 
	 * => ASCII 코드는 영어를 표기하기 위해 만든 코드로 규격 자체에 한글이 없었다가
	 * 나중에 여기에 한글이 포함되면서 EUC-KR, CP949 등의 인코딩 방식이 추가되었음.
	 * 
	 * 참고)
	 * ASCII => extended ASCII(ISO9959-1) => 조합형, 완성형(KSC5601) => 윈도우 계열: CP949  |
	 * 															  => 유닉스 계열: EUC-KR |
	 * 
	 * => ANSI계열 => EUC-KR
	 * => 유니코드(UTF-8)
	 */
	
	public static void main(String[] args) {
		FileInputStream fis = null;
		InputStreamReader isr = null;
		
		try {
			fis = new FileInputStream("d:/D_Other/test_ansi.txt");
			
			// 파일인코딩 정보를 이용하여 읽어오기
			// ex) new InputStreamReader(바이트기반 스트림 객체, 인코딩 방식);
			isr = new InputStreamReader(fis, "CP949");
			
			int data = 0;
			while ( (data = isr.read()) != -1 ) {
				System.out.print((char) data);
			}
			System.out.println();
			System.out.println("출력 끝...");
				
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				isr.close(); // 보조 스트림만 닫아도 된다.
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면11 : test_ansi.txt 파일에 반갑습니다. ANSI 계열 인코딩 방식입니다. 라고 기입해놓음. ANSI인 CP949, MS949 대신 EUC-KR로 해도 됨

 

 

package kr.or.ddit.basic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class T09FileEncodingTest {
	/*
	 * 한글 인코딩 방식에 대하여...
	 * 
	 * 한글 인코딩 방식은 크게 UTF-8 과 EUC-KR 방식 두가지로 나누어 볼 수 있다.
	 * 원래 한글 윈도우는 CP949방식을 사용했는데, 윈도우를 개발한 마이크로소프트에서 EUC-KR 방식에서 
	 * 확장하였기 때문에 MS949라고도 부른다.
	 * 한글윈도우의 메모장에서 말하는 ANSI인코딩이란 CP949(Code Page 949)를 의미한다.
	 * - CP949(MS949) => 한글 윈도우의 한글 인코딩 방식(ANSI계열)
	 * - UTF-8 => 유니코드 UTF-8 인코딩 방식
	 * - US-ASCII => 영문 전용 인코딩 방식
	 * 
	 * => ASCII 코드는 영어를 표기하기 위해 만든 코드로 규격 자체에 한글이 없었다가
	 * 나중에 여기에 한글이 포함되면서 EUC-KR, CP949 등의 인코딩 방식이 추가되었음.
	 * 
	 * 참고)
	 * ASCII => extended ASCII(ISO9959-1) => 조합형, 완성형(KSC5601) => 윈도우 계열: CP949  |
	 * 															  => 유닉스 계열: EUC-KR |
	 * 
	 * => ANSI계열 => EUC-KR
	 * => 유니코드(UTF-8)
	 */
	
	public static void main(String[] args) {
		FileInputStream fis = null;
		InputStreamReader isr = null;
		
		try {
//			fis = new FileInputStream("d:/D_Other/test_ansi.txt");
			fis = new FileInputStream("d:/D_Other/test_utf8.txt");
			
			// 파일인코딩 정보를 이용하여 읽어오기
			// ex) new InputStreamReader(바이트기반 스트림 객체, 인코딩 방식);
//			isr = new InputStreamReader(fis, "CP949");
			isr = new InputStreamReader(fis, "UTF-8");
			
			int data = 0;
			while ( (data = isr.read()) != -1 ) {
				System.out.print((char) data);
			}
			System.out.println();
			System.out.println("출력 끝...");
				
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				isr.close(); // 보조 스트림만 닫아도 된다.
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

결과 화면12 :&nbsp; test_utf8.txt 파일에 반갑습니다. UTF-8 계열 인코딩 방식입니다. 라고 기입해놓음, UTF-8 파일을 CP949로 읽을 시 글자 깨짐.

 

 

 

 

 

 

 

 

 

 

 

 

반응형