보조스트림

Java

목록 보기
25/26
post-thumbnail

1.보조 스트림

다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림
(문자변환, 입출력 성능 향상, 기본 데이터 타입 입출력, 객체 입출력 등의 기능을 제공)

  • 보조스트림 생성

    보조스트림 변수 = new 보조스트림(연결스트림)
InputStream is = System.in;
InputStreamReader reader = new InputStreamReader(is);

InputStream은 Byte기반 스트림이죠. 그런데 이 InputStream을 통해서 들어오는 데이터가 문자라면 프로그램에서 InputStream을 통해서 yte로 받는것보다 문자로 받는게 훨씬 낫겠죠. 그래서 InputStream을 맞바로 받는게 아니라 보조스트림을 달아서 하는거에요.
여기서는 보조스트림이 InputStreamReader인거에요.

  • 보조스트림 체인(보조스트에 또 다른 보조스트림이 연결될 수 있다)

2. 문자 변환 보조 스트림

  • 소스 스트림이 바이트 기반 스트림이지만 데이터가 문자일 경우 사용할 수 있다.
    - Reader와 Writer는 문자 단위로 입출력하기 때문에 바이트 기반 스트림보다는 편리.
    • 문자셋의 종류를 지정할 수 있기 때문에 다양한 문자를 입출력

2-1. InputStreamReader

InputStream is = System.in;
Reader reader = new InpuStreamReader(is);
FileInputStream fis = new FileInputStream("C:/Temp/file.txt");
Reader reader = new inputStreamReader(fis);

예시

public class InputStreamReaderExample {

	public static void main(String[] args) throws Exception {
		InputStream is = System.in;   //콘솔로부터 얻어내겠습니다.
		
		Reader reader = new InputStreamReader(is);
		int readCharNo;
		char[] cbuf = new char[100];
		
		
		//콘솔에서는 ctrl + g를 누르면 -1을 뱉어낸다. 
		while((readCharNo = reader.read(cbuf)) != -1) {
			String data = new String(cbuf,0,readCharNo);
			System.out.println(data);
		}
		reader.close();
		//오리지날 스트림도 close해주는게 좋겠죠.
		is.close();
	}
}

2-2. OutputStreamWriter

FileOutputStream fos = new FileOutputStream("C:/Temp/file.txt");
Writer writer = new FileOutputStream(fos);

예제

public class OutputStreamWriterExample {

	public static void main(String[] args) throws Exception {
		
		FileOutputStream fos = new FileOutputStream("C:/Temp/file.txt");
		
		Writer writer = new OutputStreamWriter(fos);
		
		String data = "바이트 출력 스트림을 어쩌구";
		
		writer.write(data);
		writer.flush();
		writer.close();
		System.out.println("파일 저장이 완료되었습니다.");
	}
}

3. 성능 향상 보조 스트림

  • 입출력 성능에 영향을 미치는 입출력 소스
    - 하드 디스크
    • 느린 네트워크
  • 버퍼를 이용한 해결
    - 입출력 소스와 직접 작업하지 않고 버퍼(vuffer)와 작업하므로 실행 성능을 향상

    프로그램은 쓰기 속도가 향상
    버퍼가 차게되면 데이터를 한꺼번에 하드디스크로 보냄으로서 출력 횟수를 줄여줌

3-1. BufferedInputStream, BufferedReader

public class BufferedInputStreamExample {
	public static void main(String[] args) throws Exception {
		
		FileInputStream fis = new  FileInputStream("C://Users//heeju//eclipse-workspace//aaa//src//sec05//exam01_InputStreamReade/image.png");
		
		BufferedInputStream bis = new BufferedInputStream(fis);
		while(bis.read() != -1) {
			
		}
	}
}

3-2. BufferedOutputStream과 BufferedWriter

  • 보조스트림 두개 인 경우
public class BufferedReaderExample {

	public static void main(String[] args) throws Exception {
		InputStream is = System.in;
		
		Reader reader = new InputStreamReader(is);
		BufferedReader bf = new BufferedReader(reader);
		
		System.out.print("입력:");
		//입력한 라인 전체를 읽어주는 readLine().  read()도 있고 여러 메서드가 있지만. 
		String lineString = bf.readLine();
		System.out.print("출력:"+lineString);
		
		bf.close();
		reader.close();
		is.close();
		
	}
}

예시

public class BufferedOutputStreamExabple {
	public static void main(String[] args) throws Exception {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		int data;
		
		fis = new FileInputStream("C://Users//heeju//eclipse-workspace//aaa//src//sec05/image.png");
		bis = new BufferedInputStream(fis);
		fos = new FileOutputStream("C:/Temp/image.png");
		bos = new BufferedOutputStream(fos);
		
		while((data = bis.read())!=-1) {
			bos.write(data);
		}
		
		fos.flush();
		bos.close(); fos.close(); bis.close(); fis.close();		
        }
}

4. 기본 타입 입출력 보조 스트림

DataInputStream dis = new DataInputStream(바이트 입력 스트림);
DataOutputStream dos = new DataOutputStream(바이트 입력 스트림);

파일이 없으면 만들어서 출력하는 방법

	public static void main(String[] args) throws Exception {
		//파일 없으면 만들어서. 할 수 있군....
		FileOutputStream fos =new FileOutputStream("C:/Temp/primitive.dat");
		DataOutputStream dos = new DataOutputStream(fos);
		
		dos.writeUTF("홍길동");  //문자열 저장할 경우
		dos.writeDouble(95.5);	//double값을 저장할 경우
		dos.writeInt(3);		//int값을 저장할 경우
		
		dos.flush();
		dos.close();
		fos.close();
		
	}
}

↑여기서 만든 파일을 읽기

public class DataInputOutStreamExample {
	public static void main(String[] args) throws Exception {
    
		FileInputStream fis = new 						FileInputStream("C:/Temp/primitive.dat");
		DataInputStream dis = new DataInputStream(fis);
		
		//저장된 순서에 맞게 읽기
		String name = dis.readUTF();
		double score = dis.readDouble();
		int order = dis.readInt();
		
	}
}

5. 프린터 보조 스트림


개행을 자주한다면 사용하는게 좋습니다.

PrintStrea ps = new PrintStream(바이트출력스트림);
PrintWriter pw = new PrintWriter(문자출력스트림);

public class Ex3 {

	public static void main(String[] args) throws Exception {
		FileOutputStream fos = new FileOutputStream("C:/Temp/file.txt");
		//output스트림이라 printWiter가 아니라 printStream으로 연결했습니다.
		PrintStream ps = new PrintStream(fos);
		
		ps.println("[프린터 보조 스트림]");
		ps.println("마치");
		ps.println("프린터가 출력하는 것처럼");
		ps.println("데이터를 출력합니다");
		
		ps.flush();
		ps.close();
		fos.close();	
	}
}

5-1. printf(형식화된 문자열)



%d : 정수를 의미. 정수가 이 기호 대신 들어갑니다.

%f : 실수를 의미. 실수가 이 기호 대신 들어갑니다.
%-10s : 문자열 들어갈 10자리 확보해라. 나머지는 공백으로.

%1$쇼 : 1번째 매개값 어쩌구.

6. ObjectInputStream, ObjectOutputstream

  • 객체를 바이트 배열로 만드는 작업을 직렬화 : ObjectOutputstream
  • 객체를 inputStream을 통해 받는. 배열->객체 역직렬화 : ObjectInputStream
  • 객체를 파일 또는 네트워크로 입출력 할 수 있는 기능 제공
ObjectInputStream ois =  new ObjectInputStream(바이트 입력 스트림);
ObjectOutputstream oos = new ObjectOutputstream(바이트 출력 스트림);

oos.writeObject(객체)
객체타입 변수 = (객체타입) ois.readObject();
예제 - 내보내기

public class ObjectInputStreamEx {

	public static void main(String[] args) throws Exception{
		
		FileOutputStream fos = new FileOutputStream("C:/Temp/Object.dat");
		ObjectOutputStream oos = new ObjectOutputsStream(fos);

		oos.writeObject(new Integer(10));
		oos.writeObject(new Double(3.14));
		oos.writeObject(new int[] {1,2,3});
		oos.writeObject(new String("홍길동"));
		
		oos.flush();
		oos.close();
		fos.close();	
	}
}

예제 - 읽어오기

		FileInputStream fis = new FileInputStream("C:/Temp/Object.dat");
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		Integer obj1 = (Integer) ois.readObject();
		Double obj = (Double) ois.readObject();
		int[] obj3 = (int[]) ois.readObject();
		String obj4 = (String) ois.readObject();
		
		ois.close();
		fis.close();

6-1. 직렬화가 가능한 클래스(Seriazable)

  • 자바는 Seriazable인터페이스를 구현한 클래스만 직렬화 할 수 있도록 제한
  • 바이트화 돼서 객체 배열로.
  • 직렬화로 내보내기
public class SerializableExample {

	public static void main(String[] args) throws Exception {
		FileOutputStream fos = new FileOutputStream("C:/Temp/Object.dat");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		
		ClassA classA = new ClassA();
		classA.field2.field1 = 2;
		ClassA.field3 = 3;
		
		oos.writeObject(classA);
		oos.flush(); oos.close(); fos.close();	
	}
}
  • 읽어오기
		FileInputStream fis = new FileInputStream("C:/Temp/Object.dat");
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		ClassA v = (ClassA) ois.readObject();
		System.out.println(v.field1);
		System.out.println(v.field2);
		System.out.println(v.field3);

6-2. serialVersion필드

  • 직렬화된 객체를 역직렬화할 때는 직렬화했을 떄와 같은 클래스를 사용(당연)
  • 클래스의 이름이 같더라도클래스의 내용이 변경된 경우 역직렬화는 실패
  • serialVersionUID는 같은 클래스임을 알려주는 식별자 역할
  • 불가피한 수정이 있을 경우 명시적으로 serialversionUID를 선언
    static.final long serialVersionUID = 정수값;
    ↑ serialver.exe로 자동 생성 가능



    이후

    한다면,

    이 classC객체를 더이상 사용 불가능해 에러남.
    ois.readObject()이 시리얼번호를 읽을 때 불일치 해서 생기는 일.
    모르겠으면 1시간 46분경
    현재 폴더의 경로 복사(properties에서) cmd에서
    cd 경로 엔터

    패키지명과 클래스명 후 엔터

6-3. writeObject()와 readObject() 메소드


재정의할 때 꼭 저 보라색 코드를 넣어야함.
추가하고자 하는 코드는 초록색 네모칸 안에.

  • 언제 필요한가?

    Parent는 Seriazable 구현 안하고
    child는 Seriazable 구현.
    필드 2만 배열화돼서 출력되고 필드1은 출력이 되지 않습니다.
    parent는 Seriazable 구현하고 child는 구현 안하면 자동으로 상속돼서 ㄱㅊㄱㅊ.
    그런데 반대의 경우에는 안됨.

    반드시! 접근 제한자는 private여야합니다.
    실행하면↓

0개의 댓글