일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Java
- redis
- Collection
- 자바
- spring
- OS
- mysql
- gradle
- SpringBoot
- Stream
- K8s
- JPA
- 스프링
- list
- 보조스트림
- 토비의 스프링 정리
- thread
- 이스티오
- Stack
- IntellJ
- Real MySQL
- jvm
- 스트림
- Kotlin
- 토비의 스프링
- 자바 ORM 표준 JPA 프로그래밍
- 백준
- GC
- 쿠버네티스
- MSA
- Today
- Total
인생을 코딩하다.
[Java] 바이트 단위 입출력 스트림 본문
바이트 단위 스트림
InputStream : 바이트 단위 입력 스트림 최상위 클래스
OutPutStream : 바이트 단위 출력 스트림 최상위 클래스
추상 메서드를 포함한 추상 클래스로 하위 클래스가 구현하여 사용
주요 하위 클래스
스트림 클래스(입력) | 설명 |
FileInputStream | 파일에서 바이트 단위로 자료를 읽는다. |
ByteArrayInputStream | Byte 배열 메모리에서 바이트 단위로 자료를 읽는다. |
FilterInputStream | 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스. |
스트림 클래스(출력) | 설명 |
FileOutputStream | 바이트 단위로 파일에 자료를 쓴다. |
ByteArrayOutputStream | Byte 배열에 바이트 단위로 자료를 쓴다. |
FilterOutputStream | 기반 스트림에서 자료를 쓸 때 추가 기능을 제공하는 보조 스트림의 상위 클래스. |
FileInputStream과 FileOutputStream 사용하기
- 파일에 한 바이트씩 자료를 읽고 쓰는데 사용 (한 바이트이기 때문에 문자는 못 읽는다. 한글같이 멀티바이트인 경우는 FileReader, FileWriter를 쓰면 된다.)
- 입력 스트림은 파일이 없는 경우에 예외 발생 (입력 스트림은 읽을 파일이 지정되있는데 없다면, FileNotFoundException이 뜬다.)
- 출력 스트림은 파일이 없는 경우 파일 생성하여 출력 (없으면 생성을 해준다.)
FileInputStream 예제 1
package java8.stream.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputTest1 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("input.txt");
int i;
// // 한 바이트씩 3번 읽어보자.
// i = fis.read();
// System.out.print((char) i);
// // read()에 빨간줄로 에러가 뜰때 try~catch로 또 감싸주어도 되지만, 아래에 FileNotFoundException이 있기 때문에
// // 그냥 IOException로 바꿔주면 된다. FileNotFoundException은 IOException에 속하기 때문
// i = fis.read();
// System.out.print((char) i);
// i = fis.read();
// System.out.print((char) i);
// 끝까지 읽어보자자, 파일에 끝에 도달하면 -1이 반한됨, -1이 아닐때까지 계속
while ((i = fis.read()) != -1) {
System.out.print((char) i);
}
} catch (IOException e) {
e.printStackTrace(); // 어디에서 에러가 발생하였는지 추적할 수 있게
} finally {
try {
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("end");
}
}
abcabcabcabcã
ã´ã
ã
ã´ã
end
// 한 바이트만 읽기 때문에 멀티바이트인 한글은 깨진다
Try-With-resources를 이용하여 처리했을때 (JDK 7이상에서 가능)
public class FileInputTest1 {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("input.txt")) {
int i;
while ((i = fis.read()) != -1) {
System.out.println((char) i);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
결과 값은 똑같다.
예제 2
package java8.stream.inputstream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputTest2 {
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("input2.txt")) {
int i;
byte[] bs = new byte[10];
while ((i = fis.read(bs)) != -1) {
for(byte b : bs) {
System.out.print((char)b);
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
jeonghyungilonetwothree
// input2.txt
// 결과
jeonghyung
ilonetwoth
reenetwoth
jeonghyung
ilonetwoth
ree
여기까지 읽었는데 그 뒤 netwoth는 byte[] bs = new byte[10];(Buffer)에 남은 Garbage다. (JAVA - GC에 관한 글 참고)
오버라이드가 안되었기 때문에 그 뒤에 남은 것이 들어온다.
이런 경우에는 읽은 갯수만큼 알아야한다. 통채로 출력하면 Garbage가 출력될 수 있기 때문에..
읽은 갯수가 i에 반환이 된다. byte[] bs = new byte[10]; 으로 읽지 않은 경우에는 char로 한 바이트씩 반환이 되었지만,
byte[] bs = new byte[10];(Buffer)로 읽었기 때문에 갯수가 반환이 된다. 그래서 아래 예제와 같이 구현해주면 원하는 값이 출력 되는 것을 볼 수 있다.
package java8.stream.inputstream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputTest2 {
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("input2.txt")) {
int i;
byte[] bs = new byte[10];
while ((i = fis.read(bs)) != -1) {
// for(byte b : bs) {
// System.out.print((char)b);
// }
for(int k = 0; k < i; k++) {
System.out.println((char)bs[k]); // 읽은 갯수만큼 출력, i가 읽은 갯수
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
jeonghyung
ilonetwoth
ree
Buffer을 쓸 때, Garbage가 나올 수 있는 것을 유의하며 써야 좋을 것 같다.
FileOutputStream 예제
txt 파일을 따로 생성하지 않아도 65, 66, 67 아스키코드를 읽어 'output.txt' 파일에 A,B,C가 작성되어 파일이 자동 생성되는 것을 볼 수 있다.
try(FileOutputStream fos = new FileOutputStream("output.txt", true))
뒤에 true를 붙이면 Append가 되어서 'output.txt'에 ABCABC로 계속 이어져서 쓰이게 된다.
FileOutputStream & FileInputStream 예제
package java8.stream.outputstream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputTest2 {
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;
data++;
}
try(FileOutputStream fos = new FileOutputStream("alpha.txt", true);
FileInputStream fis = new FileInputStream("alpha.txt")) {
fos.write(bs);
int ch;
while((ch = fis.read()) != -1) { // 하나씩 읽음
System.out.print((char)ch);
}
}catch (IOException e) {
System.out.println(e);
}
}
}
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
'Java' 카테고리의 다른 글
[Java] 보조 스트림 (0) | 2020.11.24 |
---|---|
문자 단위 입출력 스트림 (0) | 2020.11.24 |
[Java] 입출력 스트림 (0) | 2020.11.19 |
[Java] Generic (0) | 2020.11.19 |
[Java] String,String, String +, StringBuffer, StringBuilder, Wrapper Class, boxing & unboxing (0) | 2020.11.19 |