일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 이클립스
- Linux
- SQL
- CentOS8
- java
- 중첩쿼리
- Python
- 오류
- 주민번호마스킹
- 파이썬
- https
- Oralce
- 서울복층에어비앤비
- monthPicker
- 자바기초스터디
- JavaScript
- 8kyu
- 사용자변경
- Codewars
- class파일바로보기
- 6kyu
- 이것이리눅스다
- Eclipse
- 7kyu
- 시즌1
- 멀티쓰레드프로그래밍
- 서울에어비앤비
- 남산타워뷰
- VMware
- CentOS
- Today
- Total
보통사람
[Study-13주차] I/O(입출력) 본문
-
목표
-
자바의 Input과 Ontput에 대해 학습하세요.
-
-
학습할 것(필수)
-
스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
-
InputStream과 OutputStream
-
Byte와 Character 스트림
-
표준 스트림 (System.in, System.out, System.err)
-
파일 읽고 쓰기
-
1. 스트림(Stream) / 버퍼(Buffer) / 채널 (Channel) 기반의 I/O
1.1. 스트림(Stream) 기반의 I/O
-
단방향통신만 가능함 따라서 입력과 출력을 동시에 하려면 입력스트림, 출력스트림이 필요함
-
Queue 구조처럼 먼저 보낸 데이터를 먼저 받게됨(FIFO)
-
java.io 패키지에서 사용함
1.2. 버퍼(Buffer) 기반의 I/O
-
실제 데이터를 주고받는 스트림이 아니어서 입출력 할 수 없음
-
스트림의 기능을 향상시키거나 다른 기능을 추가 할 수 있음
-
기반 스트림을 먼저 생성한 다음에 이를 이용해서 보조 스트림을 생성해야 함
FileReader fReader = new FileReader("test.txt"); // 기반 스트림 생성
BufferedReader br = new BufferedReader(fReader); // 보조 스트림 생성
...
br.read();
br.flush();
br.close();
-
FilterInputStream, FilterOutputStream은 모든 보조 스트림의 조상
-
기반 스트림이 필요하기 때문에 단순히 기반 스트림의 메소드를 그대로 호출함
-
기반스트림의 close(), flush()를 호출 할 필요없이 보조 스트림에 있는걸로 호출하기만 하면 됨
1.3. 채널(Channel) 기반의 I/O
-
양방향 입출력이 가능
-
항상 버퍼를 이용해서 입출력을 함
-
java.nio 패키지에서 사용함
2. InputStream과 OutputStream
2.1. InputStream
-
InputStream Class의 주요 메소드
-
read() : byte 단위로 데이터를 읽어오며(0~255 사이의 값) 데이터가 없으면 -1을 반환함
-
close() : 입력 스트림 자원을 닫음
-
available() : 읽어 올 수 있는 데이터의 크기를 반환함
-
skip() : 주어진 길이만큼 데이터를 건너뜀
-
mark() : 현재 위치를 표시해 놓음
-
reset() : 마지막으로 mark()가 호출되었던 위치로 되돌아감
-
-
markSuppoprted()을 통해서 mark(), reset()을 사용 할 수 있는 스트림인지 확인하고 사용해야 함
2.2. OutputStream
- OutputStream의 주요 메소드
-
write() : 데이터를 출력함
-
flush() : 버퍼에 있는 모든 출력 자원을 사용함(버퍼가 있는 출력스트림인 경우에만 의미가 있음)
-
close() : 출력 스트림 자원을 닫음
-
※ 참조
-
프로그램 종료시 닫지 않은 스트림을 JVM이 자동적으로 닫아 주긴 하지만 반드시 다 사용한 후에는 close()를 호출해야 한다.
-
예외적으로 메모리를 사용하는 스트림과 표준 입출력 스트림은 따로 닫아주지 않아도 된다.
3. Byte와 Character 스트림
3.1.Byte 스트림
-
1Byte로 처리함
-
InputStream, OutputStream이 바이트기반 스트림의 조상
-
byte 배열을 이용
3.2. Character 스트림
-
문자 데이터를 이용할 때 사용
-
바이트기반의 스트림으로 2Byte인 데이터를 처리하는데 어려움이 있어서 이를 보완하기 위해서 제공됨
-
2Byte로 처리를 하며 유니코드간의 변환을 자동적으로 처리해 줌
-
Reader, Writer가 문자 스트림의 조상
-
char 배열을 이용
4. 표준 스트림 (System.in, System.out, System.err)
4.0. System Class
-
final 클래스로 상속 및 인스턴스를 만들 수 없음
public final class System {
...
}
-
표준 입력, 표준 출력 및 오류 출력 스트림 기능이 있으며
외부에서 정의된 속성 및 환경 변수에 대한 정보 제공,
배열 일부를 빠르게 복사하기 위한 유틸리티 메소드가 있음 - 별도의 스트림을 생성하는 코드를 작성하지 않아도 자동적으로 생성됨
4.1. 표준 입출력
-
System.in
-
콘솔로부터 데이터를 입력받을 때 사용
-
반환타입이 InputStream
-
public final static InputStream in = null;
-
System.out
-
콘솔로 데이터를 출력할 때 사용
-
반환타입이 PrintStream
-
public final static PrintStream out = null;
-
System.err
-
콘솔로 오류 데이터를 출력할 때 사용
-
반환타입이 PrintStream
-
public final static PrintStream err = null;
4.2. 표준입출력의 대상변경
-
setIn() : 표준 입력 스트림을 지정한 대상으로 재할당함
-
setOut() : 표준 출력 스트림을 지정한 대상으로 재할당함
-
setErr() : 표준 오류 출력 스트림을 지정한 대상으로 재할당함
PrintStream ps = null;
FileOutputStream output = null;
String filePath = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13\\test.txt";
try {
output = new FileOutputStream(filePath);
ps = new PrintStream(output);
System.setOut(ps); // 출력대상을 파일로 변경
} catch (Exception e) {
e.printStackTrace();
}
// System.out은 파일로 대상을 변경했기 때문에 System.err 내용만 나옴
System.out.println("## System.out ##");
System.err.println("## System.err ##");
[ 실행결과 ]
## System.err ##
5. 파일 읽고 쓰기
5.0. File Class
-
File 인스턴스는 파일 또는 디렉토리일수도 있음
-
File 인스턴스는 변경 할 수 없으며 일단 생성되면 File 객체의 경로는 절대로 변경되지 않음
- OS마다 파일 경로 구분자, 파일명 구분자가 다르기 때문에 File class에는 static 변수를 이용하는 것이 좋음
// OS에 사용하는 경로 구분자를 반환( 윈도우 : ';' / 유닉스 : ':' )
public static final char pathSeparatorChar = fs.getPathSeparator();
public static final String pathSeparator = "" + pathSeparatorChar;
// OS에 사용하는 이름 구분자를 반환( 윈도우 : '\' / 유닉스 : '/' )
public static final char separatorChar = fs.getSeparator();
public static final String separator = "" + separatorChar;
System.out.println("## File.pathSeparator = " + File.pathSeparator);
System.out.println("## File.pathSeparatorChar = " + File.pathSeparatorChar);
System.out.println("## File.separator = " + File.separator);
System.out.println("## File.separatorChar = " + File.separatorChar);
[ 실행결과 ]
## File.pathSeparator = ;
## File.pathSeparatorChar = ;
## File.separator = \
## File.separatorChar = \
5.1. 파일 생성
-
File 인스턴스를 생성한다고 파일이 생성되는 것이 아님
(File 인스턴스 생성 != 파일 생성) -
createNewFile() : 빈 파일을 생성하지만 이미 생성되어 있으면 만들지 않음
// 1. 파일 경로만으로 File 인스턴스 생성
String filePath = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13";
File file = new File(filePath);
System.out.println("## file.exists() = " + file.exists());
System.out.println("## file.getPath() = " + file.getPath());
System.out.println("============================================");
// 2. 파일 경로, 파일명으로 File 인스턴스 생성
String filePath2 = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13\\";
String fileName2 = "file2.txt";
File file2 = new File(filePath2, fileName2);
System.out.println("## file2.exists() = " + file2.exists());
System.out.println("## file2.getPath() = " + file2.getPath());
System.out.println("============================================");
// 3. 파일 경로+파일명으로 File 인스턴스 생성
String filefullPath = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13\\file3.txt";
File file3 = new File(filefullPath);
// File 인스턴스 생성 != File 생성
// 파일명까지 넣은 경우 해당 위치에 파일이 있어야함
try {
file3.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("## file3.exists() = " + file3.exists());
System.out.println("## file3.getPath() = " + file3.getPath());
System.out.println("============================================");
[ 실행결과 ]
## file.exists() = true
## file.getPath() = D:\project\workspace\studyhalle\src\main\java\s1\week13
============================================
## file2.exists() = false
## file2.getPath() = D:\project\workspace\studyhalle\src\main\java\s1\week13\file2.txt
============================================
## file3.exists() = true
## file3.getPath() = D:\project\workspace\studyhalle\src\main\java\s1\week13\file3.txt
============================================
5.2. 파일 쓰기
String fileFullPath = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13\\writeFile.txt";
String str ="파일 쓰기 테스트 입니다!!";
try ( FileWriter fWriter = new FileWriter(fileFullPath);
BufferedWriter bw = new BufferedWriter(fWriter); ) {
bw.write(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e){
e.getStackTrace();
}
5.3. 파일 읽기
String fileFullPath = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13\\writeFile.txt";
try ( FileReader fReader = new FileReader(fileFullPath);
BufferedReader br = new BufferedReader(fReader); ) {
String line = "";
while ( (line = br.readLine()) != null ) {
System.out.print(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e){
e.getStackTrace();
}
[ 실행결과 ]
파일 쓰기 테스트 입니다!!
5.4. RandomAccessFile
-
하나의 클래스로 파일에 대한 입출력이 모두 가능함(DataInput, DataOutput 인터페이스를 모두 구현)
-
기본 자료형 단위로 데이터를 입출력 할 수 있음
-
내부적으로 파일포인터 때문에 파일의 어느 위치에서나 읽기, 쓰기가 가능함
int[] tmpArr = { 1, 10, 100, 1000, 2, 20, 200, 2000 };
// int배열의 데이터를 txt에 저장한 다음 출력함
String filePath = "D:\\project\\workspace\\studyhalle\\src\\main\\java\\s1\\week13\\testRandomAccess.txt";
String mode = "rw";
try {
RandomAccessFile file = new RandomAccessFile(filePath, mode);
for (int i=0; i<tmpArr.length; i++) {
file.writeInt(tmpArr[i]);
}
file.seek(0); // write()하면서 파일포인터가 마지막으로 이동했기때문에 포인터의 위치를 다시 처음으로 이동시킴
// while(true) {
// 아무것도 읽지 못하고 EOFException이 발생하는 것을 방지함
while(file.length() != file.getFilePointer()) {
System.out.println(file.readInt());
}
} catch (Exception e) {
e.printStackTrace();
}
-
testRandomAccess.txt 파일이 생성이 되지만 안의 내용은 알아 볼 수 없음
※ 참조
'Study' 카테고리의 다른 글
[Study-14주차] 제네릭(Generics) (0) | 2021.02.23 |
---|---|
[Study-12주차] 어노테이션(Annotation) (0) | 2021.01.31 |
[Study-11주차] Enum (0) | 2021.01.26 |
[Study-9주차] 예외 처리 (0) | 2021.01.12 |
[Study-8주차] 인터페이스 (0) | 2021.01.04 |