포인트!!
1. 입출력의 개념
2. 통로 개념(Stream, Connection)
3. 자원 반환
✍입출력(IO)
IO : Input과 Output의 약자
컴퓨터 내부 또는 외부 장치와 프로그램 간의 데이터를 주고 받는 것
장치와 입출력을 위해서는 하드웨어 장치에 직접 접근이 필요한데 다양한 매체에 존재하는 데이터들을 사용하기 위해 입출력 데이터를 처리할 공통적인 방법으로 스트림 이용
장치뿐 아니라 프로그램간에서도 IO 가능
Stream : 데이터가 한 방향으로만 흐른다.
ex)
입력 스트림 : (키보드로 입력 받아 ) Scanner
출력 스트림 : System.out.print()
1. File 클래스
파일 시스템의 파일을 표현하는 클래스 파일 크기, 파일 속성, 파일 이름 등의 정보와 파일 생성 및 삭제 기능 제공
File 객체 생성
:파일 시스템의 파일을 표현하는 클래스 파일 크기, 파일 속성, 파일 이름 등의 정보와 파일 생성 및 삭제 기능 제공
1. 이미 존재하는 파일 또는 폴더를 선택해서 다룸
2. 존재하지 않는 파일 또는 폴더를 생성
파일/디렉토리 생성 및 삭제 메소드
1) 존재하지 않는 파일 test1.txt 파일을 현재 프로젝트 폴더에 생성
public void example1() {
File f1 = new File("test1.txt"); // ()안에 경로를 적어야한다.
// 상대경로(현재 위치 기준)
try {
if( f1.createNewFile() ) { // 파일 실행이 성공해서 true면 반환하는 if문
//에러 IOException :예외처리가 되지 않았다. => 예외 처리 필요하다
System.out.println("파일 생성 성공");
}else { //실패했을 경우
System.out.println("파일이 이미 존재합니다. ");
}
} catch(IOException e) {
System.out.println("파일 생성 중 예외 발생");
e.printStackTrace();
// 발생한 예외, 예외의 경로를 모두 출력
}
}
➡ 절대 경로 : C: 이런 주소
상대 경로 : 현재 위치를 기준으로 한다. 예제는 현재 프로젝트인 13_IO 폴더(프로젝트)이다.
👉 .printStackTrace()
: 발생한 예외, 예외의 경로를 모두 출력
👉 boolean createNewFile()
- 파일 생성 메서드
- 생성 성공시 true, 실패 시 false 반환
실패 이유 : 이미 파일이 존재하면 실패
파일생성에 성공해도 프로젝트 explorer에서 바로 확인되지 않기때문에
새로고침해서 확인!
2. 스트림(Stream) 클래스
Stream : 서로 다른 프로그램 또는 장치간의 (입출력한) 데이터가 이동하는 통로(기본적으로 단방향)
-> 바이트 기반 스트림(1byte), 문자 기반 스트림(2byte)
입출력 장치에서 데이터를 읽고 쓰기 위해서 자바에서 제공하는 클래스
모든 스트림은 단방향이며 각각의 장치마다 연결할 수 있는 스트림 존재
하나의 스트림으로 입출력을 동시에 수행할 수 없으므로 동시에 수행하려면 2개의 스트림 필요
분류
:파일 시스템의 파일을 표현하는 클래스 파일 크기, 파일 속성, 파일 이름 등의 정보와 파일 생성 및 삭제 기능 제공
한글이나 다른 언어의 문자들은 바이트 기반 스트림에 들어갈 수 없다.
바이트 기반 스트림 : 사진
문자 기반 스트림 : 글자를 읽고 쓰는 용도
참고) 스트림 클래스 종류
색이 있는 것은 기반 스트림, 색이 없는 것은 보조 스트림 ( 효율성을 높이기 위해 사용)
바이트 기반 스트림
1) FileInputStream
파일에 작성된 내용을 1byte씩 입력 받는 스트림
-> FileInputStream 객체 생성 시 FileNotFoundException 예외 발생 가능성이 있어 이를 처리해야한다.
폴더, 파일 생성 ->
비어있는 파일에 내용을 작성해서 자바 안으로 불러오기
InputStream을 이용해 외부에 있는 inputTest1.txt를 불러들여오기
public void example2() {
FileInputStream fis = null; // FileInputStream 참조 변수 선언.
try { //예외처리가 생길 수 있으니 미리 try-catch
fis = new FileInputStream("byte/inputTest1.txt"); //byte 안에있는 inputTest1.txt을 연결해주는 스트림 fis
// 상대 경로(현재 위치를 기준으로 한다 == 13_IO 프로젝트)
// / : 경로 위치 구분
while(true) { //파일안에 몇글자가 있을지 모르니 true인 동안 무한히 받아온다.
int data = fis.read(); // 1BYTE씩 읽어 int 형태로 담는다.
if(data == -1) { //int read의 특징으로 더이상 읽어올 데이터가 없으면 반복을 멈추는 조건
break;
}
//여기서 print (data)를하면 전부 int로 받아오는데 강제형변환
System.out.print( (char)data);
// int -> char 강제 형변환해서 읽어들인 문자를 그대로 출력
}
}catch( IOException e) {
e.printStackTrace();
}
}
}
➡ FileInputStream : 기본자료형이 아니기 때문에 참조형
FileInputStream fis = null; // FileInputStream 참조 변수 선언.
👉 .read()
: 외부에 있는 파일에 작성된 내용을 1byte씩 내부로 읽어들인다.
더이상 읽어올 데이터가 없으면 -1 반환
➡ IOExecption 을 발생시킬 수 있다.
👉catch( IOException e) { }
: 예외처리에 다형성이 적용된 형태
IOException은 FileNotFoundException의 부모(상위)이기 때문에
다형성이 적용되어 발생되는 IOException, FileNotFoundException 모두 처리 가능
결과에서 한글이 이상하게 나오는 이유
아스키 코드(1byte)
: 영어, 숫자, 특수문자, 명령어
유니코드 (2byte)
:전 세계 각국의 문자 + 새로운 특수 기호
🔎 선언과 초기화를 나누어서 하는이유!!!
: FileInputStream은 지역변수 안에있어서 try-catch밖에 있는 finally에서 사용할 수 가 없으니
바깐에 미리 선언한다.
👉 .close()
: 자원반환
FileInputStream을 닫음 (안쓰는 통로를 닫아서 없애버린다)
== 연결이 끊어짐
== FileInputStream 통로가 메모리로 반환
➡ 자원 반환
2) FileOutputStream
1byte 단위로 프로그램 -> 파일로 쓰기 (출력)
➡ 내용
public void example3() {
// 1) FileOutputStream 참조 변수 선언
FileOutputStream fos = null;
// 2) try-catch-finally 작성
try {
// 4) FileOutputStream 객체 생성
fos = new FileOutputStream("byte/outputTest1.txt", true);
// 5) Scanner로 입력 받은 문자열을 하나의 변수에 저장
Scanner sc = new Scanner(System.in);
String str = "";
for(int i=0; i<3; i++) {
System.out.print("입력 : ");
str += sc.nextLine() + "\n"; //입력받은걸 str에 누적
}
// 6) stream에 연결된 파일로 출력하기
// void write( 문자 )
for(int i=0; i<str.length(); i++) {
fos.write( str.charAt(i)); //i번째 인덱스 뽑아내기
}
}catch(IOException e) {
e.printStackTrace();
}finally {
// 3) 사용한 스트림 자원 반환
try {
fos.close(); //try-catch쓰는 이유는 위의 예제 참고
} catch (IOException e) {
e.printStackTrace();
}
}
}
👉 4) ()안에 출력할 파일 경로 작성하는데
1) 아직 존재하지 않는 파일이라면 -> 경로에 작성된 파일이 존재하지 않으면 자동으로 새 파일을 생성
2) 존재하는 파일이라면 -> 재실행하고 입력하면 덮어쓰기된다
만약! 이어쓰기 하고싶다면 4)에서 경로 적고나서 ( 경로, true);
false가 기본값으로 덮어쓰기되는거고
true를 작성하면 이어쓰기 된다.
문자 기반 스트림
3) FileReader
파일 -> 프로그램으로 문자(2byte) 단위로 읽어오는 문자기반 스트림
새 폴더 생성 : char
파일 : inputTest1 을 복사해 inputTest2로 리네임
public void example4() {
FileReader fr = null;
try {
fr = new FileReader("char/inputTest2.txt");
while(true) {
int data = fr.read(); //read() 를 하면 한 문자씩 읽어온다. 읽어올게 없으면 -1 반환
if(data == -1) {
break; //꼭 if는 중간에 넣어야한다...
}
System.out.print((char)data);
// int -> char로 다운캐스팅
} //2byte 크기의 통로로 한글도 깨지지 않는다!!
}catch(IOException e) {
e.printStackTrace();
} finally {
//닫아주는게 좋기때문에 finally에 close작성
// -> 그리고 예외처리도 하기
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
➡ FileReader : 파일 -> 프로그램으로 문자(2byte) 단위로 읽어오는 문자기반 스트림
2) FileWriter
: 프로그램 -> 파일
내부에서 외부로 출력하는writer
public void example5() {
FileWriter fw = null;
// 객체를 생성하고 닫는 변수를 하나로 만들기 위해서 위에 선언
try {
fw = new FileWriter("char/outputTest2.txt");
// () 안에 경로, true : 이어쓰기
// false : 덮어쓰기
Scanner sc = new Scanner(System.in);
String str = ""; //입력받을 변수 str
for(int i =0; i<3; i++ ) {
System.out.print("입력 : ");
str += sc.nextLine() + "\n";
}
fw.write(str);
System.out.println("파일 출력 완료");
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
👉 FileWriter.write(문자열)
: 문자열을 한번에 출력한다.
문자를 하나씩 넣는게 아니라 하나의 문자열을 통으로 내보낸다.
3. 보조 스트림(Stream) 클래스
스트림의 기능을 향상시키거나 새로운 기능을 추가하기 위해 사용
보조 스트림은 실제 데이터를 주고 받는 스트림이 아니기 때문에 입출력 처리 불가능
기반 스트림을 먼저 생성한 후 이를 이용하여 보조 스트림 생성
보조 스트림 종류
- 문자 변환(InputStreamReader/OutputStreamWriter)
- 입출력 성능(BufferedInputStream/BufferedOutputStream)
- 기본 데이터 타입 출력(DataInputStream, DataOutputStream)
- 객체 입출력(ObjectInputStream/ObjectOutputStream) 등의 기능을 제공하는 보조스트림이 있음
FileInputStream fis = new FileInputStream("sample.txt"); //기반 스트림 생성
BufferedInputStream bis = new BufferedInputStream(fis); //보조스트림 생성
bis.read(); //보조스트림으로부터 데이터 읽어옴
Buffered : 임시공간
객체 입출력 보조 스트림
객체를 파일 또는 네트워크로 입출력 할 수 있는 기능 제공
단, 객체는 문자가 아니므로 바이트 기반 스트림으로 데이터를 변경해주는 직렬화 필수
직렬화 =
객체 직렬화 시 private 필드를 포함한 모든 필드를 바이트로 변환
역직렬화 --
직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스 사용 단, 클래스 이름이 같더라도 클래스 내용이 변경된 경우 역직렬화 실패
문자 변환 보조 스트림
소스 스트림이 바이트 기반 스트림이지만 데이터가 문자일 경우 사용 Reader와 Writer는 문자 단위로 입출력을 하기 때문에 데이터가 문자인 경우 바이트 기반 스트림보다 편리하게 사용 가능
'Backend > Java' 카테고리의 다른 글
[JDBC] JDBC 개요, 객체 선언 (0) | 2021.10.06 |
---|---|
[Java] Collection_Map (0) | 2021.10.06 |
[Java] Collection_Set (0) | 2021.10.06 |
[Java] Collection_ List (0) | 2021.10.06 |
[Java] Scanner 주의사항/ .next()와 .nextline() 차이 (0) | 2021.09.16 |