I/O란 Input과 Output의 약자로, 입력과 출력 간단히 줄여서 입출력이라고 부른다.
입출력은 컴퓨터 내부 또는 외부의 장치와 프로그램 간의 데이터를 주고받는 것을 의미
스트림
- 자바에서 입출력을 수행하려면, 두 대상을 연결하고, 데이터를 운반할 수 있는 운반통로가 필요함.
- 스트림이란 데이터를 운반하는데 사용되는 연결통로이다.
- 스트림은 단방향 통신만 가능하다.
- 입력과 출력을 동시에 수행하려면, 입력을 위한 입력 스트림과 출력을 위한 출력 스트림이 필요하다.
바이트 기반 스트림
- 스트림은 바이트 단위로 데이터를 전송하며, 입출력 대상에 따라 다음과 같은 입출력 스트림이 있다.
입력스트림 | 출력스트림 | 입출력 대상의 종류 |
FileInputStream | FileOutputStream | 파일 |
ByteArrayInputStream | ByteArrayOutputStream | 메모리(바이트 배열) |
PipedInputStream | PipedOutputStream | 프로세스(프로세스간 통신) |
AudioInputStream | AudioOutputStream | 오디오장치 |
- 위는 모두 InputStream과 OutputStream의 자손으로, 각각 읽고 쓰는데 필요한 추상메서드가 있다.
InputStream | OutputStream |
abstract int read() | abstract void write(int b) |
int read(byte[] b) | void write(byte[] b) |
int read(byte[] b, int off, int len) | void write(byte[] b, int off, int len) |
- InputStream의 read()와 OutputStream의 write(int b)는 입출력의 대상에 따라 읽고 쓰는 방법이 다르기에, 각 상황에 맞게 구현하라는 뜻으로 추상메서드로 정의되어 있다.
보조 스트림
- 스트림 외에도 스트림의 기능을 보완하기 위한 보조 스트림이 제공된다.
- 보조 스트림은 실제 데이터를 주고받는 스트림이 아니기 때문에, 데이터를 입출력 할 수 있는 기능은 없지만 스트림의 기능을 향상시키거나 새로운 기능 추가 가능
// 기반 스트림 생성
FileInputStream fis = new FileInputStream("test.txt");
// 기반 스트림을 이용해서 보조 스트림 생성
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read();
- 입력 성능을 향상 시키기 위해 버퍼를 사용하는 보조스트림인 BufferedInputStream을 사용하는 코드로, 실제 입력기능은 FileInputStream이 수행하고, BufferedInputStream은 버퍼만을 제공한다.
- InputStream은 FilterInputStream의 조상이며, FilterInputStream은 BufferedInputStream, DataInputStream, DigestInputStream, LineNumberInputstream, PushbackInputStream의 조상이다.
입력 | 출력 | 설명 |
FilterInputStream | FilterOutputStream | 필터를 이용한 입출력 처리 |
BufferedInputStream | BufferedOutputStream | 버퍼를 이용한 입출력 성능향상 |
DataInputStream | DataOutputStream | int,float과 같은 기본형 단위로 데이터를 처리하는 기능 |
SequenceInputStream | 없음 | 두개의 스트림을 하나로 연결 |
LineNumberInputStream | 없음 | 읽어온 데이터의 라인 번호를 카운트 |
ObjectInputStream | ObjectOutputStream | 데이터를 객체 단위로 읽고 쓰는데 사용. 파일을 이용하며 객체 직렬화와 연관 있음 |
없음 | PrintStream | 버퍼를 이용하며, 추가적인 print관련 기능 |
PushbackInputStream | 없음 | 버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능(unread, push back to butter) |
문자기반 스트림
- Java에서는 한 문자를 의미하는 char형이 1byte가 아니라 2byte이기 때문에 바이트기반의 스트림으로 2byte인 문자를 처리하는데에 어려움이 잇음 -> 이 점을 보완하기 위해 문자기반의 스트림이 제공됨
바이트기반 스트림 | 문자기반 스트림 |
FileInputStream FileOutputStream |
FileReader FileWriter |
ByteArrayInputStream ByteArrayOutputStream |
CharArrayReader CharArrayWriter |
PipedInputStream PipedOutputStream |
PipedReader PipedWriter |
-InputStream -> Reader
-OutputStream -> Writer
* 바이트 기반 스트림과 문자 기반 스트림의 읽기와 쓰기에 사용되는 메서드를 비교한 표
InputStream | Reader |
abstract int read() int read(byte[] b) int read(byte[] b, int off, int len) |
int read() int read(char[] cbuf) abstract int read(char[] cbuf, int off, int len) |
OutputStream | Writer |
abstract void write(int b) void write(byte[] b) void write(byte[] b, int off, int len) |
void write(int c) void write(char[] cbuf) abstract void write(char[] cbuf, int off, int len) void write(String str) void write(String str, int off, int len) |
- byte배열대신 char배열을 사용한다는 점, 추상메서드가 달라짐
* 문자기반 보조 스트림
바이트기반 보조 스트림 | 문자기반 보조 스트림 |
BufferedInputStream BufferedOutputStream |
BufferedReader BufferedWriter |
FilterInputStream FilterOutputStream |
FilterReader FilterWriter |
PrintStream | PrintWriter |
PushbackInputStream | PushbackReader |
바이트기반 스트림
InputStream과 OutputStream
- InputStream과 OutputStream은 모든 바이트기반의 스트림의 조상이며, 다음과 같은 메서드가 있다.
InputStream의 메서드
메서드명 | 설명 |
int available() | 스트림으로부터 읽어올 수 있는 데이터의 크기를 반환한다. |
void close() | 스트림을 닫음으로써 사용하고 있던 자원을 반환한다. |
void mark(int readlimit) | 현재 위치를 표시해놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 돌아갈 수 있다. 매개변수 readlimit은 되돌아갈 수 있는 byte의 수 |
boolean markSupported() | mark()와 reset()을 지원하는지 알려줌 |
abstract int read() | 1바이트를 읽어오며, 더 이상 읽어올 데이터가 없을 경우 -1을 반환한다. abstract메서드이기 때문에 InputStream의 자손들은 상황에 맞게 구현해야함. |
int read(byte[] b) | 배열 b의 크기만큼 읽어서 배열을 채우고 읽어온 데이터의 수를 반환한다. 반환하는 값은 항상 배열의 크기보다 작거나 같다. |
int read(byte[] b, int off, int len) | 최대 len개의 byte를 읽어서, 배열 b의 지정된 위치(off)부터 저장한다. 실제로 읽어올 수 있는 데이터가 len개보다 적을 수 있다. |
void reset() | 스트림에서의 위치를 mark()가 호출되었던 위치로 되돌린다. |
long skip(long n) | 스트림에서 주어진 길이만큼 건너뛴다. |
OutputStream의 메서드
메서드명 | 설명 |
void close() | 입력소스를 닫음으로써 사용하고 있던 자원을 반환한다. |
void flush() | 스트림의 버퍼에 있는 모든 내용을 출력 소스에 쓴다. |
abstract void write(int b) | 주어진 값을 출력 소스에 쓴다. |
void write(byte[] b) | 주어진 배열 b에 저장된 모든 내용을 출력 소스에 쓴다. |
void write(byte[] b, int off, int len) | 주어진 배열 b에 저장된 내용 중에서 off번째부터 len개만큼을 읽어서 출력 소스에 쓴다. |
- 프로그램이 종료될때, JVM이 자동적으로 닫아주기는 하지만, 스트림을 사용해서 모든 작업을 마치고 난 후에는 close()를 호출해서 반드시 닫아주어야 한다. (System.in이나 System.out과 같은 표준 입출력 시스템은 닫아줄 필요 없다고 함)
ByteArrayInputStream과 ByteArrayOutputStream
package ch15;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
public class IOEx1 {
public static void main(String[] args) {
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
byte[] outSrc = null;
ByteArrayInputStream input = null;
ByteArrayOutputStream output = null;
input = new ByteArrayInputStream(inSrc);
output = new ByteArrayOutputStream();
int data = 0;
while((data = input.read()) != -1){
output.write(data);
}
outSrc = output.toByteArray();
System.out.println("Input Source : " + Arrays.toString(inSrc));
System.out.println("Output Source: " + Arrays.toString(outSrc));
}
}
package ch15;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
public class IOEx2 {
public static void main(String[] args) {
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
byte[] outSrc = null;
byte[] temp = new byte[10];
ByteArrayInputStream input = null;
ByteArrayOutputStream output = null;
input = new ByteArrayInputStream(inSrc);
output = new ByteArrayOutputStream();
input.read(temp,0,temp.length); // 읽은 데이터를 배열 temp에 담는다.
output.write(temp,5,5); // temp[5]부터 5개의 데이터를 write합니다.
outSrc = output.toByteArray();
System.out.println("Input Source:" + Arrays.toString(inSrc));
System.out.println("temp : " + Arrays.toString(temp));
System.out.println("Output Source : " + Arrays.toString(outSrc));
}
}
package ch15;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class IOEx3 {
public static void main(String[] args) {
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
byte[] outSrc = null;
byte[] temp = new byte[4];
ByteArrayInputStream input = null;
ByteArrayOutputStream output = null;
input = new ByteArrayInputStream(inSrc);
output = new ByteArrayOutputStream();
System.out.println("Input Source: " + Arrays.toString(inSrc));
try{
while(input.available() > 0){
input.read(temp);
output.write(temp);
outSrc = output.toByteArray();
printArrays(temp,outSrc);
}
}catch(IOException e){
}
}
static void printArrays(byte[] temp, byte[] outSrc){
System.out.println("temp :" + Arrays.toString(temp));
System.out.println("Output Source: " + Arrays.toString(outSrc));
}
}
- available()은 블락킹 없이 읽어올 수 있는 바이트의 수를 반환합니다.
- 마지막 결과하면을 보면, 배열 9번째와 10번째 요소 값인 8과 9만을 출력해야하는데, temp에 남아있던 6과 7까지 같이 출려되었다. 이는 보다 나은 성능을 위해 temp에 담긴 내용을 지우고 쓰는 것이 아니라 그냥 기존의 내용에 덮어쓰기 때문이다.
package ch15;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
public class IOEx4 {
public static void main(String[] args) {
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
byte[] outSrc = null;
byte[] temp = new byte[4];
ByteArrayInputStream input = null;
ByteArrayOutputStream output = null;
input = new ByteArrayInputStream(inSrc);
output = new ByteArrayOutputStream();
try{
while(input.available() > 0){
int len = input.read(temp);
output.write(temp,0,len);
}
}catch(IOException e){
}
outSrc = output.toByteArray();
System.out.println("Input Source: " + Arrays.toString(inSrc));
System.out.println("temp :" + Arrays.toString(temp));
System.out.println("Output Source: " + Arrays.toString(outSrc));
}
}
- temp에 저장된 모든 내용을 출력하는 대신 값을 읽어온 만큼(len의 길이)만 출력하도록 변경함
FileInputStream과 FileOutputStream
- FileInputStream과 FileOutputStream은 파일의 입출력을 하기 위한 스트림
생성자 | 설명 |
FileInputStream(String name) | 지정된 파일이름을 가진 실제파일과 연결된 FileInputStream을 생성한다. |
FileInputStream(File file) | 파일의 이름을 파일 인스턴스로 지정하여 실제 파일과 연결된 FileInputStream을 생성한다. |
FileOutputStream(String name) | 지정된 파일이름을 가진 실제 파일과 연결된 FileOutputStream을 생성한다. |
FileOutputStream(String name, boolean append) | append가 true이면, 출력시 기존 파일내용의 마지막에 덧붙인다. false면, 기존의 파일 내용을 덮어쓴다. |
FileOutputStream(File file) | 파일의 이름을 String이 아닌 File인스턴스로 지정한다. |
바이트기반의 보조스트림
FilterInputStream
- FilterInputStream / FilterOutputStream은 InputStream / OutputStream의 자손이면서 모든 보조스트림의 조상이다.
- 보조스트림은 자체적으로 입출력을 수행할 수 없기 때문에 기반 스트림을 필요로 함.
- protected FilterInputStream(InputStream in)
- public FilterOutputStream(OutputStream out)
-> 단순히 기반 스트림의 메서드를 그대로 호출하며, 그 자체로는 아무일도 하지 않는다.
- > 상속을 통해 원하는 작업을 수행하도록 읽고 쓰는 메서드를 오버라이딩해야 함
BufferedInputStream과 BufferedOutputStream
- 버퍼 크기는 입력 소스로부터 한 번에 가져올 수 있는 데이터의 크기로 지정한다.
- 프로그램에서 입력소스로부터 데이터를 읽기 위해 처음으로 read메서드를 호출하면, BufferedInputStream은 입력소스로부터 버퍼 크기만큼의 데이터를 읽어다 자신의 내부 버퍼에 저장한다. 외부의 입력 소스보다 내부 버퍼에서 읽어들이는 것이 훨씬 빠르므로 작업효율 증대.
- BufferedOutputStream역시 버퍼를 이용하여 출력소스와 작업을 한다. 입력 소스로부터 데이터를 읽을때와 반대로, 프로그램에서 write메서드를 이욯나 출력이 BufferedOutputStream의 버퍼에 저장된다. 버퍼가 차면 그때부터 모든 내용을 출력소스에 출력한다.
- close()나 flush()를 호출하여 마지막에 버퍼에 남아있는 모든 내용이 버퍼에 출력되도록 해야한다.
DataInputStream과 DataOutputStream
- DataInputStream / DataOutputStream도 각각 FilterInputStream / FilterOutputStream의 자손
- DataInputStream은 DataInput인터페이스를, DataOutputStream은 DataOutput인터페이스를 구현하여, 데이터를 읽고 쓰는데 있어서 byte단위가 아닌, 8가지 기본 자료형의 단위로 읽고 쓸 수 있다는 장점이 있다.
SequenceInputStream
- 여러개의 입력 스트림을 연속적으로 연결해서 하나의 스트림으로부터 데이터를 읽는 것처럼 처리한다.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Vector;
public class SequenceInputStream {
public static void main(String[] args) {
byte[] arr1 = {0,1,2};
byte[] arr2 = {3,4,5};
byte[] arr3 = {6,7,8};
byte[] outSrc = null;
Vector v = new Vector();
v.add(new ByteArrayInputStream(arr1));
v.add(new ByteArrayInputStream(arr2));
v.add(new ByteArrayInputStream(arr3));
SequenceInputStream input = new SequenceInputStream(v.elements());
ByteArrayOutputStream output = new ByteArrayOutputStream();
int data = 0;
try{
while((data = input.read())!= -1){
output.write(data);
}
}catch(IOException e){
}
outSrc = output.toByteArray();
System.out.println("Input Source1 : " + Arrays.toString(arr1));
System.out.println("Input Source2 : " + Arrays.toString(arr2));
System.out.println("Input Source3 : " + Arrays.toString(arr3));
System.out.println("Input Source4 : " + Arrays.toString(arr4));
}
}
PrintStream
- 데이터를 기반스트림에 다양한 형태로 출력할 수 있게 print, println, printf와 같은 메서드를 오버로딩하여 제공한다.
- System클래스의 static멤버인 out과 err, 즉 System.out, Sytem.err이 PrintStream임
format | 설명 |
%d | 10진수 |
%o | 8진수 |
%x | 16진수 |
%c | 문자 |
%s | 문자열 |
%5d | 5자리 숫자. 빈자리 공백으로 채움 |
%-5d | 5자리 숫자, 왼쪽 정렬로 빈자리 공백으로 채움 |
%05d | 5자리 숫자, 빈자리는 0으로 채움 |
format | 설명 |
%s | 문자열 |
%5s | 5자리 문자열, 빈자리는 공백으로 채운다. |
%-5s | 5자리 문자열, 빈자리는 공백으로 채운다(왼쪽 정렬) |
format | 설명 |
%e | 지수형태표현 |
%f | 10진수 |
%3.1f | 출력될 자리수를 최소 3자리 |
%8.1f | 소수점 이상 최소 6자리, 소수점 이하 1자리 |
%08.1f | 소수점 이상 최소 6자리, 소수점 이하 1자리 |
%-8.1f | 소수점 이상 최소 6자리, 소수점 이하 1자리 |
format | 설명 |
\t | 탭 |
%n | 줄바꿈 문자 |
%% | % |
format | 설명 |
%tR %tH:%tM |
시분 |
%tT %tH:%tM:%tS |
시분초 |
%tD %tm/%td/%ty |
월일년 |
%tF %tY-%tm-%td |
년월일 |
import java.util.Date;
public class PrintStreamEx1 {
public static void main(String[] args) {
int i = 65;
float f = 1234.56789f;
Date d = new Date();
System.out.printf("문자 %c의 코드는 %d%n", i, i);
System.out.printf("%d는 8진수로 %o, 16진수로 %x%n",i,i,i);
System.out.printf("%3d%3d%3d\n",100,90,80);
System.out.println();
System.out.printf("123456789012345678901234567890%n");
System.out.printf("%s%-5s%5s%n","123","123","123");
System.out.println();
System.out.printf("오늘은 %tY년 %tm월 %td일입니다.%n",d,d,d);
System.out.printf("지금은 %tH시 %tM분 %tS초 입니다. %n",d,d,d);
System.out.printf("지금은 %1$tH시 %1$tM분 %1$tS초입니다.%n",d);
}
}
문자기반 스트림
- 문자기반 스트림과 그 자손들은 여러 종류의 인코딩과 자바에서 사용하는 유니코드간의 변환을 자동적으로 처리해준다. Reader는 특정 인코딩을 읽어서 유니코드로 변환하고, Writer는 유니코드를 특정 인코딩으로 변환해서 저장한다.
package ch15;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderEx1 {
public static void main(String[] args) {
try{
String fileName = "test";
FileInputStream fis = new FileInputStream(fileName);
FileReader fr = new FileReader(fileName);
int data = 0;
while((data=fis.read()) != -1){
System.out.print((char)data);
}
System.out.println();
fis.close();
//FileReader를 이용해서 파일내용을 읽어 화면에 출력
while((data=fr.read()) != -1){
System.out.print((char)data);
}
System.out.println();
fr.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
StringReader와 StringWriter
package ch15;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
public class StringReaderWriterEx {
public static void main(String[] args) {
String inputData = "ABCD";
StringReader input = new StringReader(inputData);
StringWriter output = new StringWriter();
int data = 0;
try{
while((data = input.read())!=-1){
output.write(data);
}
}catch(IOException e){
}
System.out.println("Input Data : "+ inputData);
System.out.println("Output Data: " + output.toString());
// System.out.println("Output Data : " + output.getBuffer().toString());
}
}
- 입출력 대상이 메모리인 스트림으로, StringWriter에 출력되는 데이터는 내부의 StringBuffer에 저장되며,
StringBuffer getBuffer()와 String to String() 메서드를 이용하여 저장된 데이터를 얻을 수 있다.
문자기반의 보조스트림
- BufferedReader / BufferedWriter는 버퍼를 이용해서 입출력의 효율을 높일 수 있도록 해주는 역할을 합니다.
- readLine() (BufferedReader): 데이터를 라인단위로 읽을 수 있다
- newLine() (BufferedWriter): 줄 바꿈 메서드
- InputStreamReader/OutputStreamReader는 바이트 기반 스트림을 문자 기반 스트림으로 연결하는 역할 수행하며 바이트 기반스트림의 데이터를 지정된 인코딩의 문자데이터로 변환함
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderEx {
public static void main(String[] args) throws IOException {
String line = "";
try{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
System.out.println("사용중인 OS의 인코딩: " + isr.getEncoding());
do{
System.out.println("문장을 입력하세요. 마치시려면 q를 입력하세요.");
line = br.readLine();
System.out.println("입력하신 문장 : " + line);
}while (!line.equalsIgnoreCase("q"));
System.out.println("프로그램을 종료합니다.");
}catch(IOException e){}
}
}
표준 입출력과 File
- 표준입출력 : 콘솔을 통한 데이터 입력과 콘솔로의 데이터 출력을 의미한다.
- 자바에서는 표준 입출력을 위해 3가지 입출력 스트림, System.in, System.out, System.err을 제공한다.
- System.in : 콘솔로부터 데이터를 입력받는데 사용
- System.out : 콘솔로부터 데이터를 출력하는데 사용
- System.err : 콘솔로부터 데이터를 출력하는데 사용
- File : 자바에서는 File클래스를 통해서 파일과 디렉터리를 다루고 있음
package ch15;
import java.io.File;
import java.io.IOException;
public class FileEx1 {
public static void main(String[] args) throws IOException {
File f = new File("C:\\Users\\ME\\Documents\\GitHub\\Java-Practice\\src\\ch15\\FileEx1.java");
String fileName = f.getName();
int pos = fileName.lastIndexOf(".");
System.out.println("경로를 제외한 이름 - " + f.getName());
System.out.println("확장자를 제외한 파일 이름 - " + fileName.substring(0,pos));
System.out.println("확장자 - " + fileName.substring(pos+1));
System.out.println("경로를 포함한 파일이름 - " + f.getPath());
System.out.println("파일의 절대 경로 - " + f.getAbsolutePath());
System.out.println("파일의 정규 경로 - " + f.getCanonicalPath());
System.out.println("파일이 속해있는 디렉토리 - " + f.getParent());
System.out.println();
System.out.println("File.pathSeparator - " + File.pathSeparator);
System.out.println("File.pathSeparatorChar - " + File.pathSeparatorChar);
System.out.println("File.separator - " + File.separator);
System.out.println("File.separatorChar - " + File.separatorChar);
System.out.println();
System.out.println("user.dir=" + System.getProperty("user.dir"));
System.out.println("sun.boot.class.path=" + System.getProperty("sun.boot.class.path"));
}
}
직렬화
- 직렬화란 객체를 데이터 스트림으로 만드는 것을 뜻하며, 객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 것임
- 역직렬화란 반대로 스트림으로부터 데이터를 읽어서 객체를 만드는 것이다.
- 직렬화(스트림에 객체 출력)에는 ObjectOutputStream을 사용하며, 역직렬화(스트림으로부터 객체를 입력)할때는 ObjectInputStream을 사용한다.
- ObjectInputStream과 ObjectOutputStream은 각각 InputStream과 OutputStream을 직접 상속받지만, 기반 스트림을 필요로 하는 보조 스트림이다. 따라서 객체를 생성할때 입출력할 스트림을 지정해주어야 함.
- writeObject와 readObject를 통해 직렬화를 수행함
- 직렬화가 가능한 클래스를 만드려면, 직렬화하고자 하는 클래스가 java.io.serializable 인터페이스를 구현하도록 하면 된다.
- 조상 클래스가 serializable 인터페이스를 구현하였으면, 해당 자손 클래스도 직렬화가 가능하다.
- 최고 조상 Object는 직렬화 될 수 없다. -> Object가 Serializable하면 모든 클래스가 직렬화될 수 있기 때문에..?
- 제어자 transient키워드를 붙여서 직렬화 대상에서 제외될 수 있도록 할 수 있다.
package ch15;
import java.io.Serializable;
public class UserInfo implements Serializable {
String name;
String password;
int age;
public UserInfo(){
this("UnKnown","1111",0);
}
public UserInfo(String name, String password, int age){
this.name = name;
this.password = password;
this.age = age;
}
@Override
public String toString() {
return "(" + name + "," + password + "," + age + ")";
}
}
package ch15;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class SerialEx1 {
public static void main(String[] args) {
try{
String fileName = "UserInfo.ser";
FileOutputStream fos = new FileOutputStream(fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream out = new ObjectOutputStream(bos);
UserInfo u1 = new UserInfo("JavaMan","1234",30);
UserInfo u2 = new UserInfo("JavaWoman","4321",26);
ArrayList<UserInfo> list = new ArrayList<>();
list.add(u1);
list.add(u2);
out.writeObject(u1);
out.writeObject(u2);
out.writeObject(list);
out.close();
System.out.println("직렬화가 잘 끝났습니다.");
}catch (IOException e){
e.printStackTrace();
}
}
}
package ch15;
import java.io.*;
import java.util.ArrayList;
public class SerialEx2 {
public static void main(String[] args) throws IOException {
try{
String fileName = "UserInfo.ser";
FileInputStream fis = new FileInputStream(fileName);
BufferedInputStream bis = new BufferedInputStream(fis);
ObjectInputStream in = new ObjectInputStream(bis);
UserInfo u1 = (UserInfo) in.readObject();
UserInfo u2 = (UserInfo) in.readObject();
ArrayList list = (ArrayList) in.readObject();
System.out.println(u1.toString());
System.out.println(u2.toString());
System.out.println(list);
in.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
- 객체를 역직렬화할 때는 직렬화할때의 순서와 일치해야 한다.
- 따라서 직렬화할 객체가 많을 때는 각 객체를 개별적으로 직렬화하는 것보다 ArrayList와 같은 컬렉션에 저장해서 직렬화하는 것이 좋다.