Input/Output Stream
✅ 자바의 입출력과 Stream
❗️ Stream collection API와는 다른 개념
☑️ 방향 (= 일반통행)
✔️ 입력 Stream
어떤 대상으로부터 자료를 읽어들일 때 사용하는 Stream
✔️ 출력 Stream
파일에 저장하기 위해
☑️ Stream끊어 보내고 읽는 단위
bit단위로 데이터 보내기에는 너무 작고, 이걸 적당한 단위로 끊어 보내다보니 byte 또는 char
✔️ 바이트 Stream
byte (8bits)
✔️ 문자 Stream
char (2byte)
☑️ 출력 방법
- console 입출력
- file 입출력
- image 출력
✅ console 입출력
System
은 생성하지 않아도 바로 사용 가능
System.out
System.in
System.err
❗️read는 항상 IOException catch
☑️ System
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
32
33
34
35
36
37
38
39
40
41
42
43
44
//알파벳 한 개 받기
public class ConsoleTest {
public static void main(String[] args) {
//console System.in
int i=0;
System.out.println("Input here please: "); //a 넣으면
try {
i= System.in.read();
}
System.out.println("input "+ i); //97
System.out.println("input changed into(char) "+ (char) i); //a
} catch (IOException e) {
e.printStackTrace();
}
}
//문장 넣기
public class ConsoleTest {
public static void main(String[] args) {
//console System.in
int i=0;
System.out.println("Input here please: "); //i love coding넣으면
try {
StringBuilder sb= new StringBuilder();
//다음중 넘어가기 전까지 i 추가하겠다
while( (i= System.in.read()) != '\n' ){
sb.append((char)i);
}
System.out.println(sb); //i love coding
} catch (IOException e) {
e.printStackTrace();
}
}
}
☑️ Scanner
로 입력받기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) {
//System.in을 Scanner안에 넣어야 한다.
Scanner scanner= new Scanner(System.in);
System.out.println("input name please");
//한 줄을 읽기
String name= scanner.nextLine();
System.out.println("input job please");
String job= scanner.nextLine();
System.out.println("input age please");
int age= scanner.nextInt();
System.out.printf("Name is %s, job is %s, age is %d", name, job, age);
}
}
✅ file input, output
⭐️ resource 해제
finally, close로 resourece 해제
try-with-resource로 resourece 해제
input: FileInputStream 파일 읽기
output: FileOutputStream 파일 만들기, 바이트로 파일 만들기
✔️ FileInputStream
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FileInputStreamTest {
public static void main(String[] args) {
try(FileInputStream fis= new FileInputStream("src/chap56_ioStream/Test.txt")){
int i;
//-1이 되기 전까지 읽기
while((i= fis.read()) !=-1){
System.out.print((char) i);
}
}catch(FileNotFoundException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
}
✔️ FileOutputStream
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class FileOutputTest {
public static void main(String[] args) {
String content= "This is content of File";
//append
try(FileOutputStream fos= new FileOutputStream("src/chap56_ioStream/OutputTest.txt", true)){
//byte 배열로 만든다. string을 byte로 변환
//append하는 것을 true
byte[] byteArr= content.getBytes();
fos.write(byteArr);
//⭐️ 기존 파일 이어쓰기 가능, 파일 이름은 그대로 두고 내용만 바꿔도 됨.
System.out.println("txt File complete");
}catch(FileNotFoundException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
}
✔️ 한국어 쓰기 위해 FileReader
한글은 unicode로 정의되어 있어 FileInputStream, FileOutputStream으로는 불가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class FileReaderTest {
public static void main(String[] args) {
try(FileReader fr= new FileReader("src/chap56_ioStream/Test.txt")){
int i;
while((i= fr.read()) != -1 ){
System.out.print((char) i);
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
✔️ 한국어 쓰기 위해 FileWriter
1
2
3
4
5
6
7
8
9
10
11
12
13
public class FileWriterTest {
public static void main(String[] args) {
String content= "아기 자바 뚜루뚜뚜루";
try(FileWriter fw= new FileWriter("src/chap56_ioStream/FileWriterTest.txt")){
//⭐️ byte로 바꾸는 과정 필요 없이 바로 write가능
fw.write(content);
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
✅ read image
image는 2D Array로 되어 있다.
byte stream으로 바꿔 이미지를 회전시킬 수 있다.
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
public class ImageIoTest {
public static void main(String[] args){
// 이미지 파일 경로
String filePath = "src/exercise/chapter_56/Picture.png";
try {
File file = new File(filePath);
BufferedImage image = ImageIO.read(file);
// 이미지 회전하는 함수
BufferedImage rotatedImage = rotateImage(image, 90);
// 변환된 이미지 저장
String outputFilePath = "src/exercise/chapter_56/Picture2.png";
ImageIO.write(rotatedImage, "png", new File(outputFilePath));
System.out.println("이미지 파일이 만들어졌습니다.");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
✅ 보조 stream
🆚 기반 streamz
기반 stream은 직접 파일을 읽고 쓰고,
보조 stream은 기반 stream을 도와줌
- 기존 기반 stream 문자열을 지원
byte만 지원하는 기반 stream 개선
System.in으로 한국어 넣으면 깨지니까 보조 stream I/O stream 이 도와줌
- 기존 기반 stream 성능, 속도 개선
Buffered I/O는 파일 복사하는데 속도 개선
- 기존 메소드를 쉽게 사용할 수 있도록 개선
PrintWriter 쓰면 filewriter는 못 썼던 println 쓸 수 있음
💡 I/O stream
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
32
33
//기존 방법으로는 한글 읽지 못한다. ❌
public class InputStreamReaderTest {
public static void main(String[] args) {
int i;
System.out.println("Input English here please: "); //a 넣으면
StringBuilder sb= new StringBuilder();
try {
while((i = System.in.read()) != '\n') {
sb.append((char)i);
}
System.out.println(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
//💡 I/O stream으로 개선
int j;
System.out.println("Input Korean here please: "); //a 넣으면
StringBuilder sb2= new StringBuilder();
try (InputStreamReader isr= new InputStreamReader(System.in)){
while((j = isr.read()) != '\n') {
sb2.append((char) j);
}
System.out.println(sb2.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
💡 Buffered I/O
Buffered는 중복된 데이터를 효과적으로 다룸
성능이 올라가 속도 개선
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
32
33
public class BufferedStreamTest {
public static void main(String[] args) {
//기존 방법은 느림
try(FileReader fr= new FileReader("src/chap56_ioStream/ReadTest.txt");
FileWriter fw= new FileWriter("src/chap56_ioStream/WriteTest.txt")
){
int i;
while((i= fr.read()) != -1 ){
fw.write((char) i);
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
//💡 Buffer 사용해 속도 개선
try(BufferedReader bfr= new BufferedReader(new FileReader("src/chap56_ioStream/BufferedReadTest.txt"));
BufferedWriter bfw= new BufferedWriter(new FileWriter("src/chap56_ioStream/BufferedWriteTest.txt"))
){
int i;
while((i= bfr.read()) != -1 ){
bfw.write((char) i);
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
💡 PrintWriter
FileWriter로는 println, printf를 쓸 수가 없음!
그래서 PrintWriter를 사용한다
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
32
33
34
35
public class PrintWriterTest {
public static void main(String[] args) {
String filename = "src/chap56_ioStream/Test.txt"; // 출력할 파일의 이름
try (FileWriter fileWriter = new FileWriter(filename)) {
fileWriter.write("FileWriter를 사용한 예시입니다.\n");
int number = 42;
String formattedNumber = String.format("이 메서드는 형식화된 문자열을 출력합니다. 숫자: %d\n", number);
fileWriter.write(formattedNumber);
double value = 3.14;
String formattedValue = String.format("format() 메서드도 형식화된 문자열을 출력할 수 있습니다. 값: %.2f\n", value);
fileWriter.write(formattedValue);
} catch (IOException e) {
System.out.println("파일을 쓰는 도중 오류가 발생했습니다: " + e.getMessage());
}
// 💡 PrintWriter로 개선
try (PrintWriter printWriter = new PrintWriter(filename)) {
printWriter.println("FileWriter를 사용한 예시입니다.");
int number = 42;
printWriter.printf("이 메서드는 형식화된 문자열을 출력합니다. 숫자: %d\n", number);
double value = 3.14;
printWriter.printf("format() 메서드도 형식화된 문자열을 출력할 수 있습니다. 값: %.2f\n", value);
} catch (IOException e) {
System.out.println("파일을 쓰는 도중 오류가 발생했습니다: " + e.getMessage());
}
}
}
This post is licensed under CC BY 4.0 by the author.