너무 헷갈리는 개념이라 한번 정리를 하고 넘어가야할 부분인거 같아 공부해보기로 했다.
스트림이란?
- 네트웍에서 자료의 흐름이 물과 같다는 의미에서 유래
- 다양한 입출력 장치에 독립적으로 일관성 있는 입출력을 제공하는 방식
- 입출력이 구현되는 곳 : 파일 디스크, 키보드, 마우스, 메모리 네트웍 등
스트림의 구분
- 대상 기준
입력 스트림/출력스트림 (입/출)
- 자료의 종류
바이트스트림/문자스트림 (바/문)
- 기능
기반스트림/ 보조스트림 (기/보)
각 스트림에 무엇이 있는지 잘 알아야 할 것 같다.
입력스트림과 출력스트림
입력스트림
- 대상으로부터 자료를 읽어 들이는 스트림
종류 : FileInputStream, FileReader, BufferedInputStream, BufferReader 등
*input, reader 이런게 붙으면 무조건 입력 스트림이다.
출력스트림
- 대상으로 자료를 출력하는 스트림
종류 : FileOutputStream, FileWriter, BufferedOutputStream, BufferWriter 등
*output, writer 이런게 뒤에 붙으면 무조건 출력 스트림이다.
기반스트림과 보조스트림
기반스트림
- 대상에 직접 자료를 읽고 쓰는 기능의 스트림
종류 : FileInputStream, FileOutputStream, FileReader, FileWriter 등
*앞에 File이 붙으며 Input, output, reader, writer
보조스트림
- 직접 읽고 쓰는 기능은 없이 추가적인 기능을 더해주는 스트림
종류 : InputStreamReader, OutputStreamWriter, BufferedInputStream, BufferedOutputStream 등
- 보조 스트림은 직접 읽고 쓰는 기능은 없으므로 항상 기반 스트림이나 또다른 보조 스트림을 생성자 매개변수로 포함 함
표준 입출력
- System클래스의 표준 입출력 멤버
public static PrintStream out;
public static InputStream in;
public static PrintStream err
*스테틱 멤버이기 때문에 new을 써주지 않았던 것!
- System.out
: 표준 출력(모니터)스트림이다
System.out.println("나는 바본가?");
- System.in
: 표준 입력(키보드)스트림
int d = System.in.read(); // 한 바이트 읽어내기
- System.err
: 표준 에러 출력(모니터)스트림
System.err.println("데이터");
계속 무의식적으로 써오던 System.out과 Scanner 객체를 이용할 때 System.in 이 표준 입출력 멤버였다는 것을 알았다.
package stream.inputstream;
import java.io.IOException;
public class SystemInTest {
public static void main(String[] args) {
System.out.println("알파벳 여러개를 쓰고 엔터를 누르세요");
int i = 0;
try {
while((i = System.in.read())!='\n'){
System.out.print((char)i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.in.read 예제이다.
while(i=System.in.read()!= '\n')의 \n은 엔터이다. 엔터를 누르기 전까지 입력을 받겠다는 말이다.
System.in.read 는 한 바이트씩 읽는 것을 알 수 있었다.
Scanner클래스
- java.util 패키지에 있는 입력 클래스
- 문자뿐 아니라 정수, 실수 등 다른 자료형도 읽을 수 있음
- 여러 대상에서 자료를 읽을 수 있음(콘솔, 파일 등)
생성자
Scanner(File source) : 파일을 매개변수로 받아 Scanner를 생성
Scanner(InputStream source) : 바이트 스트림을 매개변수로 받아 Scanner를 생성합니다.
Scanner(String source) : String을 매개변수로 받아 Scanner를 생성합니다.
- 생성자가 다양하다!
package stream.others;
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
int num = sc.nextInt();
System.out.println(name);
System.out.println(num);
sc.close();
}
}
바이트 단위 스트림 - 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) {
FileReader fis = null; //Reader가 붙으면 입력
int i = 0;
try {
fis = new FileReader("input.txt");//문자 단위로 읽음
while((i=fis.read())!=-1) {
System.out.print((char)i);
}
}catch(IOException e) {
e.printStackTrace();
}finally {
try {
fis.close();
} catch (IOException e) {
System.out.println(e);
}catch(NullPointerException e) {
System.out.println(e);
}
}
System.out.println("end");
}
}
import java.io.FileInputStream;
import java.io.IOException;
public class InputStreamTest2 {
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("input2.txt")){
byte[] bs = new byte[10];
int i;
while((i = fis.read(bs))!=-1) {
for(int j = 0; j<i; j++) {
System.out.print((char)bs[j]);
}
System.out.println();
}
}catch(IOException e) {
System.out.println(e);
}
}
}
처음에는 이해가 안 갔는데 i의 값보다 j의 값이 작아야 한다.
바이트 배열 bs는 10의 length를 가지고 있고
문자 10개를 읽어내면 i = 10일 것이고
0~9(j의 값) 10개 가 읽히는 것이다.
바이트 단위 스트림 - OutputStream
- 바이트 단위 출력용 최상위 스트림
- 추상 메서드를 포함한 추상 클래스로 하위 클래스가 구현하여 사용
주요 하위 클래스
FileOutputStream : 바이트 단위로 파일에 자료를 씁니다.
FileArrayOutputStream : Byte배열에 바이트 단위로 자료를 씁니다.
FilterOutputStream : 기반 스트림에서 자료를 쓸 때 추가기능을 제공하는 보조 스트림의 상위 클래스
메서드
void write(int b) : 한 바이트를 출력합니다.
void write(byte[]b): b[] 배열에 있는 자료를 출력합니다.
void writebyte b[], int off, int len : b[]배열에 있는 자료의 off위치부터 len 개수만큼 자료를 출력합니다.
void flush() : 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력합니다.
void close() : 출력 스트림과 연결된 대상 리소스를 닫습니다. 출력 버퍼가 비워집니다.
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest {
public static void main(String[] args) {
byte[] bs = new byte[26];
byte data = 65;
for(int i = 0; i<bs.length; i++) {
bs[i] = data++;
}
try(FileOutputStream fos = new FileOutputStream("output.txt")){
fos.write(bs, 2, 10);
}catch(IOException e) {
System.out.println(e);
}
System.out.println("end");
}
}
output.txt
CDEFGHIJKL 저장되어 있음
문자단위 스트림-Reader
- 문자 단위로 읽는 최상위 스트림
- 하위 클래스에서 상속받아 구현 함
FileReader : 파일에서 문자 단위로 읽는 스트링 클래스
InputStreamReader : 바이트 단위로 읽은 자료를 문자로 변환해 주는 보조 스트림 클래스
BufferedReader : 문자로 읽을 때 배열을 제공하여 한꺼번에 읽을 수 있는 기능을 제공해 주는 보조 스트림
주요 메서드
int read() : 파일로부터 한 문자를 읽습니다. 읽은 값을 반환합니다.
int read(char[]buf) : 파일로부터 buf 배열에 문자를 읽습니다.
int read(char[]buf, int off, int len : 파일로부터 buf배열의 off 위치에서부터 len 개수만큼 문자를 읽습니다.
void close() : 스트림과 연결된 파일 리소스를 닫습니다.
뒤에 나올 예제인 FileWriter이다. writer.txt라는 파일이 생성되고 fw 인스턴스에 write라는 메서드를 통해 값이 저장된다.
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterTest {
public static void main(String[] args) {
try(FileWriter fw = new FileWriter("writer.txt")){
fw.write("A");
char[]cbuf = {'B', 'C', 'D'};
fw.write(cbuf);
fw.write("안녕하세요");
fw.write(cbuf, 1, 2);
fw.write("123");
}catch(IOException e) {
System.out.println(e);
}
}
}
ABCD안녕하세요CD123
'JAVA개념' 카테고리의 다른 글
배열의 복사 (0) | 2021.11.24 |
---|---|
변수의 타입 (0) | 2021.11.23 |
변수란? (0) | 2021.11.23 |
자바언어의 특징(자바의 정석) (0) | 2021.11.23 |
Gson을 사용해보자 (0) | 2021.07.01 |