입출력스트림

Seung jun Cha·2022년 10월 2일
0

1. 구분

  1. 대상 기준 : 입력스트림, 출력스트림

  2. 자료의 종류 : 바이트 스트림, 문자 스트림
    (1) 바이트 단위 스트림 : 파일을 읽고 쓸 때 사용
    (2) 문자 단위 스트림 : 인코딩에 맞게 2바이트 이상으로 처리하도록 구현된 스트림으로 바이트 단위로 문자를 처리하면 문자가 깨짐

  3. 기능 : 기반 스트림, 보조 스트림 : 직접 읽고 쓰는 기능없이 추가적인 기능을 제공

1-1 InputStream

  • 존재하는 파일의 내용을 가지고 옴

1-1 표준 입출력 스트림

  • System.in , System.out : 입력, 출력 스트림
public static void main(String[] args) {
		
	int i;
		try {
			i = System.in.read();  // 여기서 입력받아서 읽고
			System.out.println(i);  // 숫자로 출력
			System.out.println((char)i);  // 문자로 출력
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

1-2 바이트 단위 입출력 스트림

  1. InputStream : 바이트 단위 입력 스트림 최상위 추상 클래스
    (1) FileInputStream : 파일에서 1바이트 단위로 자료를 읽음
try {
			fis = new FileInputStream("파일 경로");
            // 해당하는 파일에서 바이트 단위로 읽어옴
		
			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);

(2) ByteArrayInputStream : byte 배열 메모리에서 1바이트 단위로 자료를 읽음

public static void main(String[] args) {

		try(FileInputStream fis = new FileInputStream("input.txt")){ 
			int i;
			while ( (i = fis.read()) != -1){ // 마지막 바이트까지 읽는다
            //마지막 바이트에 도달하면 -1을 리턴함
				System.out.println((char)i);
			}
			System.out.println("end");
		} catch (FileNotFoundException e) {
			e.printStackTrace();

(3) FilterInputStream

2-1 OutputStream

  • 파일을 입력한 내용을 1바이트 단위로 추가하여 생성

2-1-1 FileOutPutStream

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) {
			e.printStackTrace();
		}
  • 한꺼번에 파일 쓰기
FileOutputStream fos = new FileOutputStream("output2.txt",true); 
// true는 이전에 쓴 파일내용이 초기화 되지 않고 이어서 쓸 수 있게 설정
//default는 false로 쓸 때마다 파일이 초기화되어 처음부터 작성됨
		try(fos){ //java 9 부터 제공되는 기능
		
			byte[] bs = new byte[26];
			byte data = 65;        //'A' 의 아스키 값
			for(int i = 0; i < bs.length; i++){  // A-Z 까지 배열에 넣기
				bs[i] = data;
				data++;
			}
			
			fos.write(bs);  //배열 한꺼번에 출력하기

2. 문자 단위 스트림

2-1 입력 스트림

2-1-1 Reader

  • 파일에서 문자단위로 읽는 스트림(1바이트 X)
public static void main(String[] args) {

		try(FileReader fr = new FileReader("reader.txt")){
			int i;
			while( (i = fr.read()) != -1){
				System.out.print((char)i);
			}
		}catch (IOException e) {
			e.printStackTrace();
		}
	}

2-1-2 Writer

public static void main(String[] args) {

		try(FileWriter fw = new FileWriter("writer.txt")){
			fw.write('A');    // 문자 하나 출력
			char buf[] = {'B','C','D','E','F','G'};
			
			fw.write(buf); //문자 배열 출력
			fw.write("안녕하세요. 잘 써지네요"); //String 출력
			fw.write(buf, 1, 2); //문자 배열의 일부 출력
			fw.write("65");  //숫자를 그대로 출력
		}catch(IOException e) {
			e.printStackTrace();
		}

3. 보조스트림

  • 실제 읽고 쓰는 기능이 아닌 보조기능을 제공하는 스트림으로 생성자의 매개변수로 다른 스트림을 가진다.

3-1 InputStreamReader, OutputStreamWriter

  • 읽거나 쓸 때, 바이트단위를 문자로 변환해주는 스트림
public static void main(String[] args) {

		try(InputStreamReader isr = new InputStreamReader(new FileInputStream("reader.txt"))){
			int i;
			while( (i = isr.read()) != -1){  //보조 스트림으로 읽음
				System.out.print((char)i);
			}

3-2 Buffered

  • 약 8K의 배열이 제공되어 입출력을 보조하는 스트림
  1. BufferedInputStream, BufferedOutputStream : 바이트단위
  2. BufferedReader, BufferedWriter : 문자용
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;
  • 버퍼(buffer) : 데이터를 한 곳에서 다른 곳으로 전송할 때, 일시적으로 그 데이터를 보관하는 임시 메모리 영역으로 입출력 속도를 향상시키기 위해 사용한다

4. 직렬화

  • 자바 시스템 내부에서 사용되는 Object 또는 Data를 외부의 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술로 메모리에 있는 객체를 바이트로 변환하여 전송가능한 상태로 만드는 기술. 반대로 바이트를 객체로 변환하는 것은 역직렬화라고 한다.

  • 메모리에만 상주해 있는 객체 데이터를 그대로 영속화(persist)가 필요할 때 사용한다. 시스템이 종료되더라도 없어지지 않는 장점을 가지며 영속화된 데이터이기 때문에 네트워크로 전송도 가능하다. 하지만 직렬화를 하면 인스턴스의 내용이 외부로 유출되기 때문에 직렬화 의도를 명확하게 표현해야한다. 그리고 필요할 때 직렬화 된 객체 데이터를 가져와서 역직렬화하여 객체를 바로 사용할 수 있다.

4-1 ObjectInputStream, ObjectOutputStream

  • InputStream, OutputStream을 매개변수로 받아 생성하는 보조스트림
    .writeObject.readObject로 직렬화, 역직렬화

class Person implements Serializable{
		String name;
		String job;

	}

	public static void main(String[] args) throws ClassNotFoundException {

		Person personAhn = new Person("이순신", "대표이사");
		Person personKim = new Person("김유신", "상무이사");
		
		try(FileOutputStream fos = new FileOutputStream("serial.out");
				ObjectOutputStream oos = new ObjectOutputStream(fos)){
			
			oos.writeObject(personAhn);  // 직렬화
			oos.writeObject(personKim);
		
		}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 e) {
			e.printStackTrace();
		}
	}

0개의 댓글