on
입출력
입출력
입력 스트림 FileInputStream, FileReader, BufferInputStream, BufferedReader 등 출력 스트림 FileOutputStream, FileWriter, BufferedOutputStream, BufferedWriter 등
바이트 단위 스트림과 문자 단위 스트림
바이트 단위 스트림
- 동영상 파일, 음악 파일, 실행 파일 등의 자료를 읽고 쓸 때 사용
- FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream
- 동영상 파일, 음악 파일, 실행 파일 등의 자료를 읽고 쓸 때 사용 - FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream 문자 단위 스트림
- 바이트 단위로 자료를 처리하면 문자는 깨짐. 인코딩에 맞게 2바이트 이상으로 처리하도록 구현된 스트림
- FileReader, FileWriter, BufferedReader, BufferedWriter
기반 스트림과 보조 스트림
기반 스트림
- 대상에 직접 자료를 읽고 쓰는 기능의 스트림
- FileInputStream, FileOutputStream, FileReader, FileWriter
- 대상에 직접 자료를 읽고 쓰는 기능의 스트림 - FileInputStream, FileOutputStream, FileReader, FileWriter 보조 스트림
- 직접 읽고 쓰는 기능은 없이 추가적인 기능을 더해주는 스트림
- 직접 읽고 쓰는 기능이 없으므로 기반 스트림이나 또 다른 보조 스트림을 생성자의 매개 변수로 포함함
- InputStreamReader, OutputStreamWriter, BufferedInputStream, BufferedOutputStream
<표준 입출력 스트림>
public class Test { public static void main(String[] args) { System.out.println("알파벳 여러 개를 쓰고 [Enter]를 누르세요"); int i; try{ InputStreamReader irs = new InputStreamReader(System.in); // 보조스트림 while((i = irs.read()) != '
'){ System.out.print((char)i); } }catch (IOException e){ e.printStackTrace(); } } }
바이트 단위 입출력 스트림
InputStream
바이트 단위 입력 스트림 최상위 추상 클래스
최상위 추상 클래스 많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현함
1. 주요 하위 클래스
스트림 클래스 설명 FileInputStream 파일에서 바이트 단위로 자료를 읽음 ByteArrayInputStream byte 배열 메모리에서 바이트 단위로 자료를 읽음 FilterInputStream 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스
2. 주요 메서드
메서드 설명 int read() 1바이트 유효한 데이터에 3바이트에 각각 0을 넣어 4바이트 int로 반환 int read(byte b[]) 입력 스트림으로부터 b[] 크기의 자료를 b[]에 읽고, 바이트 수 반환 int read(byte b[], int off, int len) 입력 스트림으로부터 b[] 크기의 자료를 b[]의 off 변수 위치부처 저장하며 len 만큼 읽고 바이트 수 반환 void close() 입력 스트림과 연결된 대상 리소스를 닫음
<파일에서 한 바이트씩 자료 읽기>
class Test { public static void main(String[] args) { FileInputStream fis = null; try{ fis = new FileInputStream("input.txt"); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); } catch(IOException e){ System.out.println(e); } finally { try{ fis.close(); } catch (IOException e){ System.out.println(e); } catch (NullPointerException e){ System.out.println(e); } } System.out.println("end"); } }
<파일의 끝까지 한 바이트씩 자료 읽기 (try-with-resources)>
class Test { public static void main(String[] args) { int i; try (FileInputStream fis = new FileInputStream("input.txt")){ while((i = fis.read()) != -1){ System.out.print((char)i + " "); // A B C } } catch (IOException e){ System.out.println(e); } } }
<파일에서 바이트 배열로 자료 읽기 (배열에 남아 있는 자료가 있을 수 있음에 유의)>
class Test { public static void main(String[] args) { int i; try(FileInputStream fis = new FileInputStream("input.txt")){ byte[] bs = new byte[10]; while((i = fis.read(bs)) != -1){ /* for(int ch : bs){ System.out.print((char)ch + " "); } */ for(int j = 0; j < i; j++){ System.out.print((char)bs[j] + " "); } System.out.println(": " + i + "바이트씩 읽기"); } } catch (IOException e){ System.out.println(e); } } }
A B C D E F G H I J : 10바이트씩 읽기 K L M N O P Q R S T : 10바이트씩 읽기 U V W X Y Z : 6바이트씩 읽기
OutputStream
바이트 단위 출력 스트림 최상위 추상 클래스
최상위 추상 클래스 많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현함
1. 주요 하위 클래스
스트림 클래스 설명 FileOutputStream 파일에서 바이트 단위로 자료를 씀 ByteArrayOutputStream byte 배열 메모리에서 바이트 단위로 자료를 씀 FilterOutputStream 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스
2. 주요 메서드
메서드 설명 int write() 한 바이트를 출력 int write(byte b[]) b[] 크기의 자료를 출력 int write(byte b[], int off, int len) b[] 배열에 있는 자료의 off 위치부터 len 개수 만큼 자료를 출력 void flush() 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력 void close() 출력 스트림과 연결된 대상 리소스를 닫음. 출력 버퍼가 비워짐
<파일에 한 바이트씩 쓰기>
class Test { public static void main(String[] args) { try(FileOutputStream fos = new FileOutputStream("output.txt")){ fos.write(65); // A fos.write(66); // B fos.write(67); // C } catch (IOException e){ System.out.println(e); } System.out.println("END"); } }
<바이트 배열에 넣고 배열을 한꺼번에 파일에 쓰기>
class Test { public static void main(String[] args) throws FileNotFoundException { FileOutputStream fos = new FileOutputStream("output.txt"); try(fos) { byte[] bs = new byte[26]; byte data = 65; for (int i = 0; i < bs.length; i++) { bs[i] = data; data++; } fos.write(bs); } catch(IOException e){ System.out.println(e); } System.out.println("END"); } }
문자 단위 입출력 스트림
reader
문자 단위 입력 스트림 최상위 추상 클래스
많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현
1. 주요 하위 클래스
클래스 설명 FileReader 파일에서 문자 단위로 읽는 스트림 클래스 InputStreamReader 바이트 단위로 읽은 자료를 문자로 변환해주는 보조 스트림 클래스 BufferedReader 문자로 읽을 때 배열을 제공하여 한꺼번에 읽을 수 있는 기능을 제공하는 보조 스트림
2. 주요 메서드
메서드 설명 int read() 파일로부터 한 문자를 읽고 반환 int read(char[] buf) 파일로부터 buf 배열에 문자를 읽음 int read(char[] buf, int off, int len) 파일로부터 buf 배열의 off 위치로부터 len 개수만큼의 문자를 읽음 void close() 입력 스트림과 연결된 대상 리소스를 닫음
<파일에서 문자 읽기>
class Test { public static void main(String[] args) throws FileNotFoundException { try(FileReader fr = new FileReader("reader.txt")){ int i; while ((i = fr.read()) != -1){ System.out.print((char)i); // 안녕하세요 } }catch (IOException e){ System.out.println(e); } } }
writer
문자 단위 출력 스트림 최상위 추상 클래스
많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현함
1. 주요 하위 클래스
클래스 설명 FileWriter 파일에서 문자 단위로 출력하는 스트림 클래스 OutputStreamWriter 바이트 단위의 자료를 문자로 변환해 출력해주는 보조 스트림 클래스 BufferedWriter 문자로 쓸 때 배열을 제공하여 한꺼번에 쓸 수 있는 기능을 제공하는 보조 스트림
2. 주요 메서드
메서드 설명 int write(int c) 한 문자를 파일에 씀 int write(char[] buf) 문자 배열의 buf의 내용을 출력 int write(char[] buf, int off, int len) 문자 배열의 buf의 off 위치에서부터 len 개수의 문자를 출력 int write(String str) 문자열 str을 출력 int write(String str, int off, int len) 문자열 str의 off번째 문자로부터 len 개수만큼 출력 int flush() 출력하기 전에 출력 버퍼를 비워 출력 void close() 스트림과 연결된 리소스 닫기. 출력 버퍼도 비워짐
<파일에 문자 쓰기>
class Test { public static void main(String[] args) throws FileNotFoundException { try(FileWriter fw = new FileWriter("writer.txt")){ fw.write('A'); // A char buf[] = {'B', 'C', 'D', 'E', 'F', 'G'}; fw.write(buf); // ABCDEFG fw.write("안녕하세요"); // ABCDEFG안녕하세요 fw.write(buf, 1, 2); // ABCDEFG안녕하세요CD fw.write("65"); // ABCDEFG안녕하세요CD65 } catch (IOException e){ System.out.println(e); } System.out.println("END"); } }
보조 스트림
실제 읽고 쓰는 스트림이 아닌 보조 기능을 제공하는 스트림
생성자의 매개변수로 또 다른 스트림(기반 스트림이나 다른 보조 스트림)을 가짐
Decorator Pattern으로 구현됨
생성자 설명 protected FilterInputStream(InputStream in) 생성자의 매개변수로 InputStream을 받음 public FilterOutputStream(OutputStream out) 생성자의 매개변수로 OutputStream을 받음
- 바이트 단위로 읽거나 쓰는 자료를 문자로 변환해주는 보조 스트림
- FIleInputStream으로 읽은 자료를 문자로 변환해 주는 예
class Test { public static void main(String[] args) throws FileNotFoundException { try(InputStreamReader isr = new InputStreamReader(new FileInputStream("reader.txt"))){ int i; while((i = isr.read()) != -1){ System.out.print((char)i); // 안녕하세요 } } catch (IOException e){ System.out.println(e); } } }
- 약 8k의 배열이 제공되어 입출력이 빠르게 하는 기능이 제공되는 보조 스트림
- BufferedReader와 BufferedWriter는 문자용 입출력 보조 스트림
- BufferedInputStream과 BufferedOutputStream을 사용하여 파일 복사하는 예
- BufferedInputStream과 BufferedOutputStream을 사용하지 않으면 엄청 느림
public class Test { public static void main(String[] args) { long millisecond = 0; try(FileInputStream fis = new FileInputStream("a.zip"); FileOutputStream fos = new FileOutputStream("copy.zip"); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos)){ millisecond = System.currentTimeMillis(); int i; while( ( i = bis.read()) != -1){ bos.write(i); } millisecond = System.currentTimeMillis() - millisecond; } catch(IOException e) { e.printStackTrace(); } System.out.println("파일 복사 하는 데 " + millisecond + " milliseconds 소요되었습니다."); } }
public class FileOutputStreamTest { public static void main(String[] args) { try(FileOutputStream fos = new FileOutputStream("data.txt"); DataOutputStream dos = new DataOutputStream(fos)) { dos.writeByte(100); dos.writeChar('A'); dos.writeInt(10); dos.writeFloat(3.14f); dos.writeUTF("Test"); }catch(IOException e) { e.printStackTrace(); } try(FileInputStream fis = new FileInputStream("data.txt"); DataInputStream dis = new DataInputStream(fis)) { System.out.println(dis.readByte()); System.out.println(dis.readChar()); System.out.println(dis.readInt()); System.out.println(dis.readFloat()); System.out.println(dis.readUTF()); }catch (IOException e) { e.printStackTrace(); } } }
직렬화
인스턴스의 상태를 그대로 파일에 저장하거나 네트워크로 전송하고(serialization) 이를 다시 복원(deserialization)하는 방식
자바에서는 보조 스트림을 활용하여 직렬화를 제공
ObjectInputStream과 ObjectOutputStream
생성자 설명 ObjectInputStream(InputStream in) InputStream을 생성자의 매개변수로 받음 ObjectOutputStream(OutputStream out) OutputStream을 생성자의 매개변수로 받음
Serializable 인터페이스
직렬화는 인스턴스의 내용이 외부로 유출되는 것이므로 프로그래머가 해당 객체에 대한 직렬화 의도를 표시해야 함
구현 코드가 없는 market interface
transient : 직렬화 하지 않으려는 멤버 변수에 사용 (Socket 등 직렬화 할 수 없는 객체)
class Person implements Serializable { private static final long serialVersionUID = -1503252402544036183L; String name; String job; transient String address; // 직렬화 할 수 없는 객체 public Person() {} public Person(String name, String job){ this.name = name; this.job = job; } @Override public String toString() { return name + ", " + job; } } public class Main { public static void main(String[] args) { Person personCEO = new Person("cieldelaube", "CEO"); Person personEmp = new Person("ciel", "employee"); try (FileOutputStream fos = new FileOutputStream("serial.out"); ObjectOutputStream oos = new ObjectOutputStream(fos)){ oos.writeObject(personCEO); oos.writeObject(personEmp); } catch (IOException e){ e.printStackTrace(); } try(FileInputStream fis = new FileInputStream("serial.out"); ObjectInputStream ois = new ObjectInputStream(fis)){ Person p1 = (Person)ois.readObject(); Person p2 = (Person)ois.readObject(); System.out.println(p1); System.out.println(p2); } catch (IOException | ClassNotFoundException e){ e.printStackTrace(); } } }
Externalizable 인터페이스
writerExternal()과 readExternal() 메서드를 구현해야 함
프로그래머가 직접 객체를 읽고 쓰는 코드를 구현할 수 있음
class Person implements Externalizable { String name; String job; public Person() {} public Person(String name, String job){ this.name = name; this.job = job; } @Override public String toString() { return name + ", " + job; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeUTF(name); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = in.readUTF(); } }
그 외 다양한 클래스
File 클래스
파일 개념을 추상화한 클래스
입출력 기능은 없고, 파일의 이름, 경로, 읽기 전용 등의 속성을 알 수 있음
public class FileTest { public static void main(String[] args) throws IOException { File file = new File("C:\\javastudy\\File.txt"); file.createNewFile(); System.out.println(file.isFile()); System.out.println(file.isDirectory()); System.out.println(file.getName()); System.out.println(file.getAbsolutePath()); System.out.println(file.getPath()); System.out.println(file.canRead()); System.out.println(file.canWrite()); file.delete(); } }
RandomAccessFile 클래스
입출력 클래스 중 유일하게 파일에 대한 입력과 출력을 동시에 할 수 있는 클래스
파일 포인터가 있어서 읽고 쓰는 위치의 이동이 가능
public class RandomAccessFileTest { public static void main(String[] args) throws IOException { RandomAccessFile rf = new RandomAccessFile("random.txt", "rw"); rf.writeInt(100); System.out.println("파일 포인터 위치:" + rf.getFilePointer()); rf.writeDouble(3.14); System.out.println("파일 포인터 위치:" + rf.getFilePointer()); rf.writeUTF("안녕하세요"); System.out.println("파일 포인터 위치:" + rf.getFilePointer()); rf.seek(0); System.out.println("파일 포인터 위치:" + rf.getFilePointer()); int i = rf.readInt(); double d = rf.readDouble(); String str = rf.readUTF(); System.out.println("파일 포인터 위치:" + rf.getFilePointer()); System.out.println(i); System.out.println(d); System.out.println(str); } }
from http://yunseodozpwf.tistory.com/45 by ccl(A) rewrite - 2021-11-20 13:02:18