고래씌
[JAVA] 13-1. 입출력(IO) (File 클래스 ①) 본문
1. File 클래스
java.io.File 클래스를 가지고 파일 만드는 과정 실습
file 클래스는 꼭 IOException 입출력 예외처리를 해줘야한다.
1) 별도의 저장경로를 지정하지 않고 생성하고자하는 파일의 이름만 제시해서 생성해보기
package com.kh.chap01_file.run;
import java.io.File;
import java.io.IOException;
public class FileRun {
public static void main(String[] args) {
// java.io.File 클래스를 가지고 파일 만드는 과정 실습
try {
// 1. 별도의 저장경로를 지정하지 않고 생성하고자하는 파일의 이름만 제시해서 생성해보기
File file1 = new File("test.txt");
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2) 경로지정을 한 파일명을 제시해서 생성하기 --> 존재하는 경로를 제시해줘야한다.
package com.kh.chap01_file.run;
import java.io.File;
import java.io.IOException;
public class FileRun {
public static void main(String[] args) {
// java.io.File 클래스를 가지고 파일 만드는 과정 실습
try {
// 2. 경로지정을 한 파일명을 제시해서 생성하기 --> 존재하는 경로를 제시해줘야한다.
File file2 = new File("C:\\dev\\test.txt");
file2.createNewFile();
// file2.mkdir();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3) 폴더를 생성하고나서 그 안에 파일을 생성하는 방법
package com.kh.chap01_file.run;
import java.io.File;
import java.io.IOException;
public class FileRun {
public static void main(String[] args) {
// java.io.File 클래스를 가지고 파일 만드는 과정 실습
try {
// 3. 폴더를 생성하고나서 그 안에 파일을 생성하는 방법
String dir = "C:\\b\\c\\d\\e"; //파일을 저장할 경로 지정
File bFolder = new File(dir);
// if(bFolder.isDirectory()) // bFolder가 디렉토리(폴더)인지 확인
// bFolder.mkdir(); // makeDirectory => 1개 폴더만 만들어지는 함수
bFolder.mkdirs(); // => 여러개의 디렉토리를 만들어줄때 사용
File file3 = new File(dir + "\\test.txt"); // 폴더를 생성하고 나서 파일 생성
file3.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4) 별도의 경로 지정 없이 폴더 생성
- .isFile() => file 이냐 아니냐 ? true / false 반환
- .isDirectory() => Directory 이냐? true / false 반환
- .getName() => 파일 이름.확장자 출력
- .getParent() => 상위폴더 반환
- .length() => 파일 용량 반환
- .getAbsolutePath() => 파일의 절대경로를 가져옴
package com.kh.chap01_file.run;
import java.io.File;
import java.io.IOException;
public class FileRun {
public static void main(String[] args) {
// java.io.File 클래스를 가지고 파일 만드는 과정 실습
try {
// 4. 별도의 경로 지정 없이 폴더 생성
File folder = new File("test"); // 경로 지정을 안하면 현재 java 프로젝트 기본경로에 저장됨
folder.mkdir();
File file = new File("test\\person.txt");
file.createNewFile();
// File에서 제공하는 메소드들
System.out.println(folder.isFile()); // file이냐? // false
System.out.println(file.isDirectory()); // Directory 냐?
System.out.println("파일명 : " + file.getName()); // 이름만 나오게 하는 것
System.out.println("상위폴더 : " + file.getParent()); // 상위폴더 반환 // test
System.out.println("파일 용량 : " +file.length());
System.out.println("절대경로 : " + file.getAbsolutePath()); // 파일의 절대경로 가져옴
} catch (IOException e) {
e.printStackTrace();
}
}
}
▶ 프로그램 상의 데이터를 외부매체(모니터, 스피커, 자바프로그램, 파일 등등)로 출력하거나 입력장치(키보드, 마우스)로 입력받는 과정을 진행하고자 한다면 반드시 외부매체와의 연결통로를 만들어야한다.
(통로 == 스트림)
▶ 스트림의 특징
- 단방향 : 입력이면 입력, 출력이면 출력 즉, 입력용 출력용 스트림이 별도로 존재함.
동시에 입출력하고자 한다면 하나의 스트림으로는 불가능함
- 선입선출(FIFO) : 먼저 전달한 값이 먼저 나오게 됨
- 시간지연문제가 발생할 수 있다.
▶ 스트림의 구분
- 통로의 사이즈 :
① 바이트 스트림 : 1byte짜리가 이동할 수 있을정도의 사이즈(좁은 통로) => 문자 하나 사용할 때
② 문자 스트림 : 2byte짜리가 이동할 수 있을정도의 사이즈(넓은 통로) => 여러줄의 문자 String 사용할때
- 외부매체와의 직접적인 연결여부 :
① 기반스트림 : 외부매체와 직접적으로 연결되는 통로(스트림)이다
② 보조스트림 : 기반스트림만으로 부족한 성능을 향상시켜주는 용도의 스트림.
직접적으로 외부매체와 연결할 수 없음. 즉, 단독사용이 불가능
기반스트림을 보조해주는 역할을 한다.
=> 보조기능 : 속도향상, 자료형 변환, 객체단위 입출력 등
☞ 보조스트림 사용시 단독적으로는 사용이 불가능하므로, 따라서 반드시 기반스트림과 함께 사용해야 한다.
2. DAO(Data Access Object)
: 데이터가 보관되어 있는 공간과 직접 접근해서 데이터를 입,출력할 수 있는 클래스
현재 프로그램 → 외부매체(파일)
출력 : 프로그램 내의 데이터를 파일로 내보내기(즉, 파일에 저장)
▶ FileOutputStream : "파일"로 데이터를 1byte단위로 출력하는 스트림
3. 파일 출력
1) FileOutputStream 객체 생성 => 매개변수로 지정한 파일과 직접적으로 연결되는 통로 만듦
- 해당 파일이 존재하지 않으면 해당 파일이 생성되면서 통로가 연결됨
- 이미 존재하는 파일이라면 즉시 통로가 연결됨
▶ FileOutputStream 객체 생성
- 두번째 매개변수로 true 추가시 → 기존에 해당파일이 있을 경우 "이어쓰기" 가능
- 두번째 매개변수로 미작성시 → 기존에 해당파일이 있더라도 "덮어씌우기"
변수명 = new FileOutputStream("파일.확장자"); => 객체 생성 후 덮어씌우기
변수명 = new FileOutputStream("파일.확장자", true); => 이어쓰기
package com.kh.chap02_byte.model.dao;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileByteDao {
public void fileSave() {
FileOutputStream fos = null; // try 바깥쪽에 변수 생성.
try {
// 1. FileOutputStream 객체 생성
fos = new FileOutputStream("a_byte.txt"); // 객체 생성 후 덮어씌우기
} catch (FileNotFoundException e) {
e.printStackTrace();
}
2) 연결통로로 데이터를 내보내기(출력) : write()메소드 이용
1byte의 범위 : -128 ~ 127 까지의 범위(파일에 기록이 될때 해당 숫자의 고유한 문자가 기록됨)
▶ 변수명.write(97); => char로 자동형변환이 돼서 'a' 출력됨
▶ byte[] arr = {99, 100, 101};
변수명.write(arr); => c d e 출력
▶ 변수명.write(arr, 1, 2) => 1번 인덱스에서부터 2개만 기록해라. 100, 101 => d e 출력
package com.kh.chap02_byte.model.dao;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileByteDao {
public void fileSave() {
FileOutputStream fos = null; // try 바깥쪽에 변수 생성.
try {
// 1. FileOutputStream 객체 생성
fos = new FileOutputStream("a_byte.txt"); // 객체 생성 후 덮어씌우기
// 2. 연결통로로 데이터를 내보내기(출력) : write()메소드 이용
// 1byte의 범위 : -128 ~ 127 까지의 범위(파일에 기록이 될때 해당 숫자의 고유한 문자가 기록됨)
fos.write(97); // char으로 자동형변환이 됨 // a 출력됨
fos.write('b');
// fos.write('고'); // 글자가 깨져서 출력됨
byte[] arr = {99, 100, 101}; // c d e 출력
fos.write(arr);
fos.write(arr, 1, 2); // 1번 인덱스에서부터 2개만 기록해라. 100, 101 // d e
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
3) 스트림을 사용했으면 반드시 자원 반납하기(반드시!)
▶ 스트림을 사용했으면 반드시 자원 반납을 해주어야한다! => 변수명.close()
▶ 자원을 반납할 때 try 내부에 작성을 하면안된다. 앞에 코드가 에러가 나면 빠져나오지 못할 수 있기 때문에 변수명.close() 실행될 수 있도록 finally에 추가하여야 함!!
▶finally : 어떤 예외가 발생하든간에 반드시 실행하는 구문
▶ finally를 추가할 때 안에 try ~ catch 문도 다시 사용을 해주어야 함.
▶ finally : exception 발생 여부와 관계없이 꼭 처리해야 하는 로직 기술.
중간에 return문을 만나도 finally구문은 실행되지만 System.exit();를 만나면 무조건 프로그램 종료.
주로 java.io나 java.sql 패키지의 메소드 처리 시 이용
~
} finally {
try {
변수명.close();
}catch(IOException e) {
e.printStackTrace();
}
}
package com.kh.chap02_byte.model.dao;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileInputStream;
public class FileByteDao {
public void fileSave() {
FileOutputStream fos = null; // try 바깥쪽에 변수 생성.
try {
// 1. FileOutputStream 객체 생성 => 매개변수로 지정한 파일과 직접적으로 연결되는 통로 만듦
fos = new FileOutputStream("a_byte.txt", true); // 이어쓰기
// 2. 연결통로로 데이터를 내보내기(출력) : write()메소드 이용
fos.write(97);
fos.write('b');
byte[] arr = {99, 100, 101};
fos.write(arr);
fos.write(arr, 1, 2);
// 3. 스트림을 사용했으면 반드시 자원 반납하기(반드시!)
// fos.close(); 위코드에서 에러 발생하는 경우 실행이 안될 수 있으므로 finally에 추가
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally { // 어떤 예외가 발생하든간에 반드시 실행하는 구문
// try 내부에 작성하면 X .
// 앞에 코드가 에러가 났든 안났던 반드시 실행될 수 있도록 finally에 추가하여야한다.
try {
fos.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
4. 파일의 내용 읽어들이기
외부매체(파일) ----> 프로그램
입력 : 파일로부터 데이터를 읽어들이겠다
FileInputStream : 파일로부터 데이터를 1바이트씩 입력받는 스트림
1) FileInputStream 객체로 입력 스트림 생성
public void fileRead() {
// FileInputStream : 파일로부터 데이터를 1바이트씩 입력받는 스트림
FileInputStream fis = null;
try {
// 1. FileInputStream 객체로 입력 스트림 생성
fis = new FileInputStream("a_byte.txt"); // 존재하는 파일의 경로 제시
}
2) 통로로 데이터를 입력받기
- System.out.println((char)fis.read()); // 1byte단위로 하나씩 데이터를 읽어들이는 함수
☞ 형변환까지 해주어야 아스키코드 값으로 출력이 안되고 문자로 출력됨
- 파일에서 더이상 읽어올 데이터가 없는 경우 -1을 반환
public void fileRead() {
// FileInputStream : 파일로부터 데이터를 1바이트씩 입력받는 스트림
FileInputStream fis = null;
try {
// 1. FileInputStream 객체로 입력 스트림 생성
fis = new FileInputStream("a_byte.txt"); // 존재하는 파일의 경로 제시
// 2. 통로로 데이터를 입력받기
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println((char)fis.read());
System.out.println(fis.read()); // 파일에서 더이상 읽어올 데이터가 없는 경우 -1을 반환
}
3) 반복문을 활용하여 파일내부의 모든 데이터 읽어들이기
- 방법 ①
while(true) {
int value = 0;
value = fis.read();
if(value == -1) break;
System.out.print((char)value);
}
public void fileRead() {
// FileInputStream : 파일로부터 데이터를 1바이트씩 입력받는 스트림
FileInputStream fis = null;
try {
// 1. FileInputStream 객체로 입력 스트림 생성
fis = new FileInputStream("a_byte.txt"); // 존재하는 파일의 경로 제시
// 반복문을 활용하여 파일내부의 모든 데이터 읽어들이기
// 방법 ①
while(true) {
int value = 0;
value = fis.read();
if(value == -1) break;
System.out.print((char)value);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 3. 다쓴 자원 반납
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 방법 ②
int value = 0; X
while(fis.read()) != -1) {
System.out.print((char)value);
}
☞ 이 방법은 while(fis.read())에서 문자를 하나 불려들이고 그다음 문자가 System.out.print((char)value); 에서 실행이 되기 때문에 해당 파일의 내용이 모두 출력되지 않는다!
int value = 0; O
while((value = fis.read()) != -1) {
System.out.print((char)value);
}
☞ 변수에 저장을 안하면 fis.read()가 호출되면서 그다음 문자가 출력되기 때문에 이 방법을 해주어야 모든 문자가 출력됨
public void fileRead() {
// FileInputStream : 파일로부터 데이터를 1바이트씩 입력받는 스트림
FileInputStream fis = null;
try {
// 1. FileInputStream 객체로 입력 스트림 생성
fis = new FileInputStream("a_byte.txt"); // 존재하는 파일의 경로 제시
// 반복문을 활용하여 파일내부의 모든 데이터 읽어들이기
// 방법 ②
int value = 0;
while((value = fis.read()) != -1) { // 변수에 저장을 안하면 fis.read()가 호출되면서 그다음 문자가 출력되기 때문에
System.out.print((char)value);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 3. 다쓴 자원 반납
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
'JAVA > JAVA 기초' 카테고리의 다른 글
[JAVA] 입출력 실습문제 (0) | 2023.10.23 |
---|---|
[JAVA] 13-2. 입출력(IO) (File 클래스 ②) (1) | 2023.10.23 |
[JAVA] 예외처리 실습문제 (0) | 2023.10.20 |
[JAVA] 12-1. 예외처리(UncheckedException, CheckedException) (0) | 2023.10.20 |
[JAVA] 날짜 계산 API 문제 (0) | 2023.10.20 |