1. Stream 이란?
2. 바이트 스트림
1. 파일에 데이터 넣기
2. 파일 읽어오기
3. 파일 복사하기 프로그램
3. 문자 스트림
1. Stream 이란?
우선 Stream이라는 단어의 뜻을 살펴보면
시냇물이 흘러가는 느낌의 뜻을 가졌다.
그리고 시냇물은 그 방향이 바뀌지 않는다.
이와 같이 물의 흐름이 한쪽으로만 흐른다는 특징이 있는 것처럼
Stream 역시 한쪽 방향으로만 데이터가 흘러가는 특징을 가졌다.
그림을 보면
App과 HDD 사이에는
Stream이 존재한다.
한쪽 방향으로만 데이터의 흐름이
흘러가기에 두개의 Stream이 필요하다.(input & output)
스트림에는 크게 2가지 종류가 있다.
바이트 스트림과 문자 스트림이다.
각각 이름에서 볼 수 있듯
바이트 스트림은 바이트 단위로
데이터를 보내는 것이고
문자 스트림은
문자 단위로 데이터를 보내는 것이다.
그럼 바이트 스트림의 입출력부터 공부해 보자!
2. 바이트 스트림
1. 파일에 데이터 넣기
이클립스를 통해서
코드를 입력하고 각종 자료형을
입력 출력할 수 있는데
이렇게 입력하고 출력한 것을 HDD에 저장하지 않는다면
기존에 입력하고 출력한 데이터들은 사라지게 될 것이다.
따라서 데이터를 영구적으로 저장키위해
File형태로 데이터를 저장을 해야 한다.
그럼 바이트스트림을 이용해
사용자로부터 데이터를 받아 File에 저장하는 프로그램부터 만들어보자.
사용자로부터 데이터를 받으려면
Scanner를 써줘야 한다.
그리고 File 객체를 생성해 주고
어떤 파일 형태로 저장할지
파일명과 확장자명을 입력해 준다.
이때 파일이 저장될 경로를 지정하지 않으면
프로젝트폴더에 파일이 저장된다.
파일 경로구분자는 보통 역슬래시(\)를 사용한다.
그러나 자바에선 \을 특수문자로 인식하기에 두 번 입력해야 한다.
또한 많은 언어에서 슬래시(/)를 사용하니 앞으로 슬래시를 사용하자.
폴더가 있어야 자동생성이 가능하다.
따라서 폴더가 없다면
하위폴더까지 같이 만들어주는 기능까지 이용해서
폴더를 만들어주는 명령문을 작성해야 한다.
isDirectory()는 해당 파일이 있는지를
true, false로 리턴해주는 기능이다.
그리고 mkdirs()는
make directories로 하위폴더가 있다면
원하는 폴더와 하위폴더까지 같이 만들어주는
기능이다.
이 폴더 만들기 기능을 이용해서
하드디스크의 원하는 영역을
설정하고
폴더를 만들어준다.
그리고 이 영역에 앞으로 입력한 데이터를 저장할
txt파일명을 적어준다.
FileOutputStream을 객체로 만들면 에러가 발생한다.
그 이유는 예외 상황이 발생할 수 있기 때문이다.
따라서 에러 부분에 마우스를 올려서 try catch 문을 자동 생성하게 해 준다.
(뒤에 파라미터에 적힌 file은 위에서 설정한 file객체이고
true는 append 모드를 한다는 것으로
하나만 저장되는 것이 아니라 입력하는 만큼 계속 저장된다는 뜻)
여기서 단순히 숫자만 보낼 것이라면
fos.write(data)를 써줘도 된다.
하지만 문자열을 입력할 것이라면
바이트 배열을 만들고 문자열을 거기다 넣은 후
보내줘야 한다.
그리고 Stream 버퍼라는 곳에 찌꺼기가 남아 있을 수 있어서
화장실 변기에 물을 내리듯 flush()를 사용해
비우도록 처리해줘야 한다.
마지막으로 스트림 작업이 끝나면
연결을 끊어주는 close를 꼭 적어줘야 한다!
그럼 이렇게 내가 지정한 폴더에
잘 저장이 된 것을 알 수 있다.
2. 파일 읽어오기
그럼 반대로
저장된 데이터를 읽어오는 기능도 알아보자.
읽어올 파일의 파일명을 관리하는 객체를 우선 생성해 준다.
그리고 FileInputStream 객체를 만든다.
이때도 에러가 발생한다.
아까와 마찬가로 예외상황이 발생할 수 있기 때문인데
try catch문을 만들어주자.
그렇게 해서 바이트 하나씩
반복문을 통해 출력이 가능하다.
(여기서 -1은 더 이상 읽을 값이 없는 상태를 말한다.)
그러나 이렇게 작성하면 ASCII에 없는 한글 등은
이상하게 출력이 된다.
그 이유는 1바이트에 해당하는 부분만 가져와서
바로 출력하기 때문이다. (2바이트 이상 차지하는 글자를 그래서 출력하지 못함)
이를 해결하기 위해
1바이트씩 읽지 말고
바이트배열로 한 번에 작업할 수 있다.
우선 바이트 배열을 만들고 (1024개의 배열로)
바이트배열 안에 데이터를 넣어준다.
그리고 String 객체로 바꿔준 다음에
이를 출력하는 방식이다.
마지막으로 스트림은 작업이 끝나면
항상 닫아야 한다.
그럼 잘 읽어오는 것을 알 수 있다.
3. 파일 복사하기 프로그램
파일 복사하기 프로그램은
위의 2가지 input, output을 동시에 사용하는 프로그램이다.
기존에 있는 파일을 읽고
이를 복사해서
내가 원하는 위치에 저장시키는 구조를 가졌다.
우선 원본파일의 경로와 파일 및 확장자명을 입력해 준다.
그리고 파일을 읽어주는 스트림 객체를 만들고
읽어 들인 파일을 다른 파일로 내보내기 위해
새로 만들어질 파일의 저장경로를 만들어 준다.
저장될 경로의 파일과 파일명을 결합하고 객체를 만들어준다.
그리고 위의 파일을 저장하기 위해
FileOutputStream 객체를 만든 다음에
원본파일에서 데이터를 1바이트씩 반복적으로 읽어오면서
바로 1바이트씩 저장하는
반복문을 만든다.
여기서 write()는 저장해 주는
메소드이다.
위의 파일 읽어오기 부분과 같은 코드를
썼는데 결과가 다른 것은
바로 출력했는지, 저장하고 끝난 후 메모장을 열어본 것인지에 따라
차이가 있기 때문이다.
예를 들어 2바이트인 문자는
1바이트씩 보내고 바로 출력하면
반만 보내져서 이상한 문자가 나타난다.
그러나 1바이트씩 보내고
바로 출력하는 대신 저장하는 반복을 하면
제대로 저장이 되기 때문에 후에 메모장을 열면
제대로 보이는 것이다.
그리고 이후에 flush와 close를 꼭 해야 하며
input과 output 스트림 객체는 예외상황이 나타날 수 있으니
꼭 try catch도 써줘야 한다는 것도 잊지 말자.
3. 문자 스트림
기존 바이트스트림 방식으로는
문자열데이터를 한 줄식 또는 한 단어씩 읽고 쓰기엔 어려움이 있다.
몇 바이트를 읽어야 할지 파악하기 어렵기 때문이다.
그래서 문자열 단위로 데이터를 처리하는 문자 스트림이 나왔다.
여기선 인풋, 아웃풋이 아니라
Reader, Writer이라고 쓴다.
(한 번에 사용해서 공부해 보자)
우선 사용자로부터 데이터를 지속적으로 입력받아 저장하는 프로그램을 만들자.
스캐너 객체를 만들고
무한 반복문을 사용해 준다. (얼마나 반복할지 모르니까!)
또 if절을 사용해
exit를 입력하면
입력이 끝나게 처리해 준다.
(여기서 equalsIgnoraeCase 기능은 대문자, 소문자를 같은 글자로 보게 하는 기능)
그리고 file을 저장하기 위해 객체를 만들고
경로를 설정해 준다.
이제 문자스트림을 이용해야 한다.
FileWriter 객체를 사용해서 참조변수를 만들고
이 참조변수를 PrintWriter라는 객체를 만들 때 넣어준다.
이 객체는 print 기능 메소드 출력보다 편하게 기능을 수행해 주기 때문에
보조적으로 사용해 주는 것이다.
마지막으로 이를 출력하고
flush, close를 해준다.
그럼 이제 데이터를 입력받았으니
읽어와서 확인해 보자.
읽어온 단어들이 여러 개일 것이고
대량의 문자열 데이터일 테니
ArrayList를 사용해 준다.
문자 스트림 클래스인
FileReader를 이용해 객체를 만들어준다.
(항상 try catch 잊지 말자)
그리고 Writer를 쓸 때도 편하게 사용하도록
보조해 주는 것이 있었듯
Reader에도 있다.
바로 BufferedReader이다.
이 클래스를 이용해 다시 객체를 만들어주고
반복문을 통해 문자열이 없는 순간까지
읽어와서
ArrayList에 저장을 해준다.
그리고 반복문을 통해 출력을 하고
스트림을 닫아주면 끝이 난다.
그러면 잘 작동하는 것을 볼 수가 있다.
'# 개발 > Java' 카테고리의 다른 글
Java #14 - GUI (국비26일차) (0) | 2023.02.07 |
---|---|
Java #13 - protocol, network (국비25일차) (0) | 2023.02.06 |
Java #11 - Thread, runnable, 익명클래스, 동기화 (국비23일차) (0) | 2023.02.02 |
Java #10 -Generic, Collection API (국비22일차) (0) | 2023.02.01 |
Java #9 -오브젝트 클래스, 예외(Exception) (국비21일차) (0) | 2023.01.31 |