앞으로 5~6년 후의 목표를 '자체 서버 만들기'로 두기.
서툴더라도 서버를 만들 수 있다면 충분히 능력있는 것.
InputStream
은return
= 읽은 결과 기준OutputStream
은parameter
= 쓸 대상 기준
System.currentTimeMillis()
: 시스템 현재 시간 구하는 메서드 (return : long)
💥💥 주의!!! java 1.8부터 추가된 함수형의 stream과는 다름!!!!!! 💥💥
InputStream
- 대표 메서드 read()
OutputStream
- 대표 메서드 write()
Reader
- 대표 메서드 read()
Writer
- 대표 메서드 write()
- char 단위 연산의 목적 = '영어 이외의 언어를 처리하기 위해'
영어 알파벳은 byte 단위 연산으로 충분했지만, 영어 외의 언어는 (ex. 한글) byte 단위로 한 글자를 처리할 수 없는 경우가 발생.
이로 인해 오류가 생기면서, char 단위 연산 = 글자 단위의 연산이 필요했던 것.
(char 연산도 기반은 물론 byte 단위 연산이다)
ex)
FileOutputStream
: 파일을 byte 단위 출력 연산
InputStreamReader
: InputStream(byte 단위로 들어온 입력)에 char 단위 입력 연산
read()
: 읽기 메서드 = input 클래스 대표 메서드
write()
: 쓰기 메서드 = output 클래스 대표 메서드
flush()
: 읽은 데이터를 남김없이 털어내는 메서드.write()
와 세트로 사용.
read(byte[] buffer, int offset, int length)
: inputStream에서 offset(시작점)부터 length(개수)만큼 읽어 buffer에 담는다. (return : 읽은 개수)
write(byte[] buffer, int offset, int length)
: outputStream에서 offset(시작점)부터 length(개수)만큼 buffer에 담아 쓴다. (return : 쓴 개수)
available()
: 읽을 수 있는 남은 byte 개수를 반환 (return : int)
- buffer란? 참고
- 테스트를 통해 성능과 버퍼 크기 사이의 최적점 찾기
버퍼가 커질수록 읽고 쓰는 속도는 높아지지만, 그만큼 다른 부분에서 느려질 수 있다.- 버퍼는 heap 메모리에 저장된다. 지역변수로 만들어 사용이 끝나면 바로 삭제해야 한다.
- char연산도 같은 방식을 사용할 수 있으나, char연산으로 이용하는 데이터는 보통 크기가 작으므로 굳이 buffer를 사용할 필요가 없다.
close()
: 자원해제 메서드 = 모든 Stream 클래스 공통 사용
close()
의 중요성
: 자원 관리는 운영체제의 역할, 자원을 사용하겠다 선언하고 (에러 등으로 인해) 해제 선언을 하지 않으면 그 자원을 이후에 사용할 수 없게 됨.
외부 자원을 사용할 때면try~ catch문
에finally
를 통해 꼭close()
실행해주기
read()
,write()
: 대상에 따라 읽고 쓰는 방법이 다르므로, 내용이 정해지지 않은 abstract 메서드
- 대상 data의 next byte를 받아온다. 단 정수 데이터의 대표값은 int이므로 형변환을 줄이기 위해 return에 int를 사용한다. (실제로는 byte = 범위는 0~255) 끝에 도달하면 끝났다는 의미로 -1이 돌아온다.
(Reads the next byte of data from the input stream. ... Returns : the next byte of data, or -1 if the end of thestream is reached.)
- 패러미터로 들어온 byte를 출력한다. 단 정수 데이터의 대표값은 int이므로 형변환을 줄이기 위해 parameter로 int를 사용한다. (실제로는 byte = 범위는 0~255)
(Writes the specified byte to this output stream. ... Parameters: b - the byte.)
✅
System.in
/System.out
의 의미
System.in
: 표준입력장치 (static InputStream 객체)System.out
: 표준출력장치 (static OutputStream[PrintStream] 객체)
ctrl + z
: 표준입력장치 입력 중 '입력 끝'을 나타내는 키- `\
<try ~ resource>
: 1.7부터 가능. 자원 사용시 권한 해제finally~ close()
코드 생략 가능. (비추천)package kr.ac.green;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOEx2 {
public static void main(String[] args) {
FileOutputStream fos = null;
// try에서 에러나더라도 finally에서 close()가 실행되어야 하기 때문에 처음에 null로 초기화해둠.
// 1.7~ <try ~ resource >로 finally close() 생략 가능, 여러 객체 한 번에 닫기 가능
/*
* try(
* FileOutputStream fos1 = new FileOutputStream(f, true),
* FileOutputStream fos2 = new FileOutputStream(f, true)
* ) {
* fos.write('A');
* fos.write('B');
* fos.write('C');
* }
*/
// 1.7부터 사용 가능하고, 닫다가 실패할 경우를 대비할 수 없으며, autoCloseable을 구현하는 객체일 때만 사용 가능
File f = new File("first.txt");
try {
fos = new FileOutputStream(f, true);
// path or file 중 하나를 넣으면 됨
// 만약 물리적 파일이 없다면, 생성 후 작성함.
// FileOutputStream에 두번째 패러미터 boolean append에 true를 넣으면 기존 입력값이 저장됨.
// boolean append의 기본값은 false - append true 해주지 않으면 내용은 덮어쓰기된다. 만약 이미 있는 파일이라면 잘못 덮어쓰기 될 수도!
// 실행 전 exists()로 확인하고 사용하기
// 물리적으로는 package 아래에 있으나,
// first.txt는 상대위치로 입력됨 - 프로젝트 아래라는 현재위치에 작성됨
fos.write('I');
fos.write(' ');
fos.write('a');
fos.write('m');
fos.write(' ');
fos.write('h');
fos.write('u');
fos.write('n');
fos.write('g');
fos.write('r');
fos.write('y');
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch(Exception e) {} // 어떤 에러가 나도 그냥 무시할 때
}
}
}
- class Document
: 텍스트 내용을 관장하는 객체 (컴포넌트 x)- 메서드
getDocument()
: (return : Document)
addDocumentListener
: Document 변화를 감지하는 리스너 객체