220619_인터넷 강의_입/출력 스트림

창고·2022년 10월 21일
0

티스토리에 저장했던 글을 옮겼습니다.
https://mrcocoball.tistory.com/93

1. 입출력 스트림

(1) 입출력 스트림의 정의

  • 다양한 입출력 장치에 독립적으로 일관성있는 입출력을 입출력 스트림을 통해 제공
  • 입출력이 구현되는 곳: 파일 디스크, 키보드, 마우스, 네트웍, 메모리 등 모든 자료가 입력되고 출력되는 곳

(2) 입출력 스트림의 구분

  • 대상 기준 : 입력 스트림 / 출력 스트림
  • 자료의 종류 : 바이트 스트림 / 문자 스트림
  • 기능 :  기반 스트림 / 보조 스트림

2. 입력 스트림과 출력 스트림

(1) 입력 스트림 : 대상으로부터 자료를 읽어들이는 스트림

  • 종류 : FileInputStream, FileReader, BufferedInputStream, BufferedReader 등

(2) 출력 스트림 : 대상으로 자료를 출력하는 스트림

  • 종류 : FileOutputStream, FileWirter, BurfferedOutputStream, BufferedWritter 등
  • System.in 사용하기 예제
public class SystemInTest1 {

	public static void main(String[] args) {
		
		System.out.println("알파벳 여러 개를 쓰고 [Enter]를 누르삼");
		
		int i;
		
		try {
			InputStreamReader irs = new InputStreamReader(System.in); // byte를 int로 변경해줌
			while((i=irs.read()) != '\n') {
			// System.out.println(i);
			System.out.print((char)i);
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

3. 바이트 단위 스트림, 문자 단위 스트림

(1) 바이트 단위 스트림 : 동영상, 음악 파일, 실행 파일 등의 자료를 읽고 쓸 때 사용 (~Stream)

  • 종류 : FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream 등

2) 문자 단위 스트림 : 바이트 단위로 자료 처리하면 문자는 깨짐, 인코딩에 맞게 2바이트 이상으로 처리 (~Writer/Reader)

  • 종류 : FileReader, FileWriter, BufferedReader, BufferedWriter 등

4. 기반 스트림, 보조 스트림

  • 기반 스트림 : 대상에 직접 자료를 읽고 쓰는 기능의 스트림
  • 보조 스트림 : 직접 읽고 쓰는 기능은 없으나 추가적인 기능을 더해줌
기반 스트림 + 보조 스트림 A + 보조 스트림 B ....

5. 바이트 단위 입출력 스트림

(1) InputStream

  • 바이트 단위 입력 스트림 최상위 추상 클래스
  • 많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현함
  • 주요 하위 클래스
    | 스트림 클래스 |   |   |
    | --- | --- | --- |
    | FileInputStream | 파일에서 바이트 단위로 자료를 읽음 | |
    | ByteArrayInputStream | byte 배열 메모리에서 바이트 단위로 자료를 읽음 | |
    | FilterInputStream | 기반 스트림에서 자료 읽을 시 추가 기능 제공, 보조 스트림의 상위 클래스 | |
  • 주요 메소드
    | 메소드 |   |   |
    | --- | --- | --- |
    | int read() | 입력 스트림으로부터 한 바이트의 자료를 읽고 읽은 자료의 바이트 수 반환 | |
    | int read(byte b[]) | 입력 스트림으로부터 b[] 크기의 자료를 b[]에 읽고 읽은 자료의 바이트 수 반환 | |
    | int read(byte b[], int off, int len) | 입력 스트림으로부터 b[] 크기의 자료를 b[]의 off 변수 위치부터 len 길이 만큼 읽고 읽은 자료의 바이트 수 반환 | |
    | void close() | 입력 스트림과 연결된 대상 리소스 닫음 | |
  • 예제
public class FileInputStreamTest {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		
		try {
			fis = new FileInputStream("input.txt");
			System.out.println((char)fis.read()); // javadoc 자주 읽어보는 습관
			System.out.println((char)fis.read());
			System.out.println((char)fis.read());
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} finally {
			try {
				fis.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (Exception e2) {
				System.out.println(e2);
			}
		}
		System.out.println("end");

	}

}

public class FileInputStreamTest2 {

	public static void main(String[] args) {
		
		
		// try-with-resource 활용
		int i;
		try(FileInputStream fis = new FileInputStream("input.txt")){ 
			while ( (i = fis.read()) != -1){ // read()의 경우 값이 없으면 int -1 값을 출력하므로
				System.out.println((char)i);
			}
			System.out.println("end");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

public class FileInputStreamTest3 {

	public static void main(String[] args) {
		
		
		// try-with-resource 활용
		int i;
		try(FileInputStream fis = new FileInputStream("input2.txt")){ 

			byte[] bs = new byte[10];
			
			while ( (i = fis.read(bs)) != -1){ // read()의 경우 값이 없으면 int -1 값을 출력하므로
				
				/* for (int ch : bs) {
					System.out.print((char)ch);
				} */ // 배열에서 남아있는 자료 (UVWXYZ 이후에 QRST까지 같이 불러와짐) 가 있어서 향상된 for문 사용 x
				
				for (int j = 0; j < i; j++) {
					System.out.print((char)bs[j]);
				}
				System.out.println(" : " + i + "바이트 읽음");

			}
			System.out.println("end");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

(2) OutputStream

  • 주요 하위 클래스
    | 스트림 클래스 |   |   |
    | --- | --- | --- |
    | FileOutputStream | 파일에서 바이트 단위로 자료를 씀 | |
    | ByteArrayOutputStream | byte 배열 메모리에서 바이트 단위로 자료를 씀 | |
    | FilterOutputStream | 기반 스트림에서 자료 쓸 때 추가 기능 제공, 보조 스트림의 상위 클래스 | |
  • 주요 메소드
    | 메소드 |   |   |
    | --- | --- | --- |
    | int write() | 한 바이트를 출력 | |
    | int write(byte b[]) | b[] 크기의 자료를 출력 | |
    | int write(byte b[], int off, int len) | b[] 배열의 자료를 b[]의 off 변수 위치부터 len 길이만큼 출력 | |
    | void flush() | 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력 | |
    | void close() | 입력 스트림과 연결된 대상 리소스 닫음, 출력 버퍼 지워짐 | |
  • 예제
public class FileOutputStreamTest2 {

	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");

	}

}
public class FileOutputStreamTest1 {

	public static void main(String[] args) throws FileNotFoundException {
		
		
		FileOutputStream fos = new FileOutputStream("output.txt", true); // append를 true로 (덮어쓰기가 아니라 이어쓰기)
		try(fos) {
			
			byte[] bs = new byte[26];
			
			byte data = 65;
			for(int i = 0; i<bs.length; i++) {
				bs[i] = data++;
			}
			
			fos.write(bs);
						
		}catch(IOException e) {
			System.out.println(e);
		}
		System.out.println("end");

	}

}

6. 문자 단위 입출력 스트림

(1) Reader

  • 주요 하위 클래스
    | 스트림 클래스 |   |   |
    | --- | --- | --- |
    | FileReader | 파일에서 문자 단위로 읽는 스트림 클래스 | |
    | InputStreamReader | 바이트 단위로 읽은 자료를 문자로 변환하는 보조 스트림 클래스 | |
    | BufferedReader | 문자로 읽을 때 배열을 제공, 한 꺼번에 읽을 수 있는 기능을 제공하는 보조 스트림 클래스 | |
  • 주요 메소드
    | 메소드 |   |   |
    | --- | --- | --- |
    | int read() | 파일로부터 한 문자를 읽고 반환 | |
    | int read(char[] buf) | 파일로부터 buf 배열에 문자를 읽음 | |
    | int read(char[] buf, int off, int len) | 파일로부터 buf 배열의 off 변수 위치부터 len 길이 만큼 읽음 | |
    | void close() | 입력 스트림과 연결된 대상 리소스 닫음 | |
  • 예제 (FileReader)
public class FileReaderTest {

	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);
			}
			System.out.println();
			
		} catch (IOException e) {
			
		}
		System.out.println("end");

	}

}

(2) Writer

  • 주요 하위 클래스
    | 스트림 클래스 |   |   |
    | --- | --- | --- |
    | FileWriter | 파일에서 문자 단위로 출력하는 스트림 | |
    | OutputStreamWriter | 바이트 단위의 자료를 문자로 변환해 출력해주는 보조 스트림 | |
    | BufferedWriter | 문자로 쓸 때 배열을 제공, 한꺼번에 쓸 수 있는 기능을 제공하는 보조 스트림 | |
  • 주요 메소드
    | 메소드 |   |   |
    | --- | --- | --- |
    | 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 개수의 문자 출력 | |
    | void flush() | 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력 | |
    | void close() | 입력 스트림과 연결된 대상 리소스 닫음, 출력 버퍼 지워짐 | |
  • 예제 (FileWriter)
public class FileWriterTest {

	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("이엣타이가");
			fw.write(buf, 1,2); // 문자 배열 일부 출력
			fw.write("65"); // 숫자 그대로 출력
		} catch (IOException e) {
			
		}
		
		System.out.println("출력 완료~");

	}

}

7. 여러 가지 보조 스트림 클래스

(1) 보조 스트림의 정의

  • 보조 기능을 제공, FilterInputStream / FilterOutputStream이 이들의 상위 클래스
  • 생성자의 매개변수로 또 다른 스트림(기반 혹은 보조 스트림)을 가짐
InputStreamReader isr = new InputStreamReader(new FileInputStream());
  • 데코레이터 패턴으로 구현
    | 기반 스트림 | + 보조 스트림 1 | + 보조 스트림 2 |
    | --- | --- | --- |
    | 바이트 단위 파일 입력 스트림 | 문자로 변환 기능 추가 | 버퍼링 기능 추가 |

(2) InputStreamReader / OutputStreamWriter

  • 바이트 단위로 읽거나 쓰는 자료를 문자로 변환
  • 예제 (FileInputStream 만으로 처리하였다면 '이엣타이가' 가 아닌 깨진 형태로 출력됨)
public class InputStreamReaderTest {

	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);
			}
			System.out.println();
			
			
		} catch (IOException e) {
			
		}

	}

}

(3) BufferedInputStream / BufferedOutputStream

  • 입출력을 빠르게 하는 기능이 제공
  • 예제 (약 14MB 자료 복사 시 FileInputStream / FileOutputStream만 적용했을 때와 Buffered~ 적용 시 차이)
public class FileCopyTest {

	public static void main(String[] args) {
		
		
		long millisecond = 0;
		
		try (FileInputStream fis = new FileInputStream("공부.zip");
				FileOutputStream fos = new FileOutputStream("공부복사.zip");
			
			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 + "소요되었습니다.");

	}

}

public class FileCopyTest {

	public static void main(String[] args) {
		
		
		long millisecond = 0;
		
		try (FileInputStream fis = new FileInputStream("공부.zip");
				FileOutputStream fos = new FileOutputStream("공부복사.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 + "소요되었습니다.");

	}

}

(4) DataInputStream / DataOutputStream

  • 자료가 메모리에 저장된 상태 그대로 읽거나 쓰는 스트림
profile
공부했던 내용들을 모아둔 창고입니다.

0개의 댓글