- io : Input(입력), Output(출력)
- Input : 키보드, 마우스, HDD, SSD, File, 스캐너
- Output : 모니터, 프린터, QR, 바코드
1. 기초
package io;
import java.io.FileReader;
public class file1 {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree.txt"); //이거 try밖에 넣으면 오류남
System.out.println(fr.getEncoding()); //파일의 언어셋
System.out.println(fr.read()); //데이터 크기 (문자 단위당 ASCII 번호)
while(true) { //무한루프 : 파일 전체를 읽어 들여야함
int size = fr.read();
System.out.println(size);
System.out.println((char)size);
if(size == -1) { //해당 파일에 더 이상 읽을 내용이 없을 경우
break;
}
}
fr.close(); //읽은 파일 내용을 종료하는 메소드 //무조건 닫아줘야함 작동안함
}catch(Exception e) {
System.out.println("해당 파일을 찾을 수 없습니다.");
}
}
}
- io 사용시 필수조건 : try ~ catch
- FileReader : 문자 데이터(ASCII)를 읽는 라이브러리
- FileWriter : 문자 데이터(ASCII)를 저장하는 라이브러리
- getEncoding() :파일의 언어셋
- read() : 문자 단위당 ASCII 번호
- close() : 읽은 파일 내용을 종료하는 메소드 //무조건 닫아줘야함 작동안함
2. 파일 읽기, 쓰기
package io;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Scanner;
public class file2 {
public static void main(String[] args) {
try {
//파일 읽기
/*
FileReader fr = new FileReader("/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree.txt");
Scanner sc = new Scanner(fr);
while (sc.hasNext()) {
System.out.println(sc.nextLine());
// if(sc.nextLine().equals(null)) { //이거는 마지막 빈값까지 나와서 오류나옴 hasNext이용
// break;
// }
}
sc.close();
fr.close();
*/
//파일 쓰기
/* FileWriter : 입력 라이브러리 */
FileWriter fw = new FileWriter("/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/game_dat.txt");
Scanner sc = new Scanner(System.in);
System.out.println("입력하실 내용을 적으세요 : ");
String user = sc.nextLine();
fw.write(user); //write 메소드 : 사용자가 입력한 값을 저장 시킴
fw.write("\n룰루랄라");
sc.close();
fw.close();
}catch(Exception e) {
System.out.println(e);
System.out.println("파일 경로가 올바르지 않습니다.");
}
}
}
- hasNext() : 각각의 라인별로 체크 (true, false)
- write 메소드 : 사용자가 입력한 값을 저장 시킴
package io;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Scanner;
//~Reader, ~Writer => ASCII
//파일을 읽기, 쓰기(추가쓰기) 작동형태 예외처리 필수
//TXT 파일일 경우 저장시 언어셋을 유의하여 체크 후 파일읽기 또는 쓰기를 진행하기! (utf-8)
public class file3 {
public static void main(String[] args) {
new file3_box().file_read();
}
}
class file3_box{
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree.txt";
FileReader fr = null;
FileWriter fw = null;
Scanner sc = null;
public void file_read() { //파일 읽기
try {
this.fr = new FileReader(url);
//Scanner : input, output 다를 경우 close를 따로 사용 가능
this.sc = new Scanner(this.fr);
do {
System.out.println(sc.nextLine());
}while(this.sc.hasNext());
this.file_writer(); //파일에 글쓰기 메소드로 이동
}catch(Exception e) {
System.out.println(e);
System.out.println("파일 경로가 올바르지 않습니다.");
}finally { //여기서 닫아주는것이 정석
this.sc.close();
try {//fr은 io이기 때문에 예외처리가 필수
this.fr.close();
}catch(Exception ee) {
System.out.println(ee);
System.out.println("오류발생");
}
}
}
public void file_writer() { //파일 쓰기
try {
System.out.println("추가 내용을 입력하세요 : ");
this.sc = new Scanner(System.in);
String msg = this.sc.nextLine();
//true : 기존 데이터를 보존하며 저장 (기본설정 false : 기존데이터 삭제 후 신규 데이터 저장)
this.fw = new FileWriter(this.url, true);
this.fw.write("\n" + msg);
System.out.println("저장이 완료되었습니다.");
}catch(Exception e) {
System.out.println(e);
System.out.println("파일 경로가 올바르지 않습니다.");
}finally { //닫을땐 연거 역순으로
try {
this.fw.close();
}catch(Exception ee) {
System.out.println(ee);
System.out.println("오류발생");
}
this.sc.close();
}
}
}
- this.fw = new FileWriter(this.url, true);
- true : 기존 데이터를 보존하며 저장 (기본설정 false : 기존데이터 삭제 후 신규 데이터 저장)
3. 파일 생성, 삭제
package io;
import java.io.File;
public class file4 {
public static void main(String[] args) {
try {
// File f = new File("/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/mail.txt"); //얘는 close없음
// 생성
// f.createNewFile(); //createNewFile() : 파일을 신규 생성하는 메소드
// System.out.println("정상적으로 파일이 생성되었습니다.");
// 삭제
// f.delete();
// System.out.println("해당 파일을 정상적으로 삭제하였습니다.");
//해당 디렉토리에 파일 리스트를 출력하는 코드 (디렉토리명)
File f = new File("/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io");
File[] files = f.listFiles(); // 1차 원시배열로 변환
int w = 0;
while (w < files.length) {
System.out.println(files[w].getName());
w++;
}
} catch (Exception e) {
System.out.println(e);
}
}
}
- File 라이브러리 : 해당 경로에서 생성, 삭제, 다른 경로로 이동, 파일명 변경, 속성 변경
- createNewFile() : 파일을 신규 생성하는 메소드
- delete() : 파일을 삭제하는 메소드
- getName() : 파일명을 출력할 때 사용하는 메소드
😊응용문제
gugu.txt 파일을 이용하여 해당 파일에 데이터가 입력되도록 코드를 작성
구구단 8단 입력되도록 함
package io;
import java.io.FileWriter;
public class file5 {
public static void main(String[] args) {
file5_box fb = new file5_box();
try {
fb.gugu8_writer();
}catch(Exception e) {
System.out.println("메소드에 문제 발생");
}
}
}
class file5_box {
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/gugu.txt";
FileWriter fw = null;
public void gugu8_writer() throws Exception { // throws Exception을 사용해 try catch를 안써도 됨 호출할땐 써야함 대신 오류는 어디서 나는지 모
this.fw = new FileWriter(this.url);
int i = 1;
while (i <= 9) {
this.fw.write("8 * " + i + " = " + (8 * i) + "\n");
i++;
}
System.out.println("8단이 저장되었습니다.");
this.fw.close();
}
}
- throws Exception을 사용해 try catch를 안써도 됨
- 호출할땐 써야함 대신 오류는 어디서 나는지 모름
4. Buffered
package io;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
//Buffered
public class file6 {
public static void main(String[] args) {
try {
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/gugu.txt";
FileReader fr = new FileReader(url);
BufferedReader br = new BufferedReader(fr);
String msg = null;
/*
while((msg = br.readLine())!= null) {
System.out.println(msg);
}
*/
//위 코드를 길게 쓰면 아래 코드
while(true) {
msg = br.readLine();
if(msg != null) {
System.out.println(msg);
}else {
break;
}
}
/*
//해당 코드는 변수에 값을 이관 및 조건문에 사용하였으므로 데이터 누수가 발생
String msg = br.readLine();
if(br.readLine() != null) { //버퍼는 한번이라도 찍는 순간 날아감 조건문에 걸면 한줄이 안나옴 여기서 써서
System.out.println(br.readLine());
System.out.println(br.readLine());
}
*/
br.close();
fr.close();
}catch(FileNotFoundException fe) { //경로 전용 예외처리
System.out.println("파일 경로 문제 발생");
}catch(Exception e) {
System.out.println(e);
}
}
}
- Buffered : 메모리를 활용하여 데이터를 출력 또는 입력 (temp)
- 유의사항 : 조건문 또는 반복문에 적용시 해당 데이터가 유실될 수 있음 => 데이터 누수를 배열로 처리
- 많은 양의 데이터를 처리할 때 유리함
- readLine() : 해당 데이터 라인을 전체 읽어 출력하는 역할
- 리더는 글자 하나하나 읽어들임
- 버퍼는 글자 하나하나 읽은걸 버퍼 에 저장해뒀다가 한줄 다 되면 출력
- 메모리를 사용하기 때문에 속도는 매우 빠름
- 버퍼는 휘발성이라 코드를 한번 읽어들이면 날아가서 불러올수없음
- 변수에 저장하거나 조건문에 걸때 사라져버림
- =>버퍼를 사용해서 여기저기 쓸 경우엔 배열에 한줄한줄 저장해서 사용
buffered + 클래스 배열을 활용하여 데이터 출력
package io;
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
//buffered + 클래스 배열을 활용하여 데이터 출력
//io 사용법 및 nio를 이용하여 사용하는 방식
public class file7 {
public static void main(String[] args) throws Exception {
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/gugu.txt";
//io (web에서 핸들링할 수 있는 코드) //nio와 다름!
/*
FileReader fr = new FileReader(url);
BufferedReader br = new BufferedReader(fr); //항상 파일리더 후 버퍼리더 사용 한번에는 불가능
List<String> data = new ArrayList<>(); //txt에 있는 데이터를 빈배열에 삽입
String text = ""; //buffered에서 읽은 값 받는 변수 (안써도됨)
for(;;){
text = br.readLine(); //txt파일에 있는 한 줄 변수에 이관
if(text != null) {
data.add(text);
}else {
break;
}
}
br.close();
fr.close();
System.out.println(data);
System.out.println(data.get(1));
System.out.println(data.size());
*/
List<String> data = new ArrayList<>();
data = Files.readAllLines(Paths.get(url));
System.out.println(data);
}
}
- io와 nio 두종류 있음
- io (web에서 핸들링할 수 있는 코드)
- nio : Buffered를 기본으로 할당하고 있음
- Paths : 경로를 호출하여 데이터를 가져오는 클래스
- Path : 경로를 호출하여 데이터를 가져오는 인터페이스
- Files : File 자료형에서 좀 더 발전한 클래스
- 웹에서 첨부파일을 올릴때 nio 사용 불가 인식을 못함 -> 주로 io 사용
- API 서버를 만들때 경로를 지정한다던가 할때는 nio 사용 가능
- nio io를 쓰는 구조에 맞게 사용해야함
- 둘을 섞어쓰지는 않음!
- 웹해야하니까 io위주로 하는것을 추천 (Spring, Spring-boot는 nio 안먹음)
5. byte 자료형
- 파일의 형태 두가지
- Binary : 이미지, 동영상, 압축파일 => 메모장으로 열면 깨지는 파일들
- ASCII : txt, 코드들 => 메모장으로 열었을 때 안깨지는 파일들
package io;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
//byte 자료형 + nio 활용
public class file8 {
public static void main(String[] args) throws Exception{
String word = "abcd";
//byte의 기본 배열코드 형태는 ASCII
byte data[] = word.getBytes(); //byte는 숫자, 원시배열 무조건 사용
System.out.println(Arrays.toString(data));
//byte를 String으로 바꿔 문자로 표현 //int를 바꾸는건 불가
String unbox = new String(data); //byte의 원시배열 숫자 값을 문자로 표현
// System.out.println(unbox);
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/gugu.txt";
//readAllBytes : byte 자료형, readAllLines : String 자료
byte alldata[] = Files.readAllBytes(Paths.get(url));
System.out.println(Arrays.toString(alldata));
String unbox2 = new String(alldata);
System.out.println(unbox2);
}
}
- byte : ASCII, Binary 모두 사용할 수 있는 자료형
- 기본 배열코드 형태는 ASCII
- readAllBytes : byte 자료형, readAllLines : String 자료형
6. nio 파일 생성, 삭제
package io;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
//nio 전용 (파일 생성, 삭제 등등)
public class file9 {
public static void main(String[] args) throws Exception {
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/app.txt";
String msg = "데이터 추가 내용!";
Path p = Paths.get(url);
Files.write(p, msg.getBytes(), StandardOpenOption.WRITE);
}
}
- nio write(경로, 문자열(byte), 옵션설정)
- StandardOpenOption : 파일 형태의 삭제, 추가, 생성
- StandardOpenOption : 기존 데이터 삭제 후 새로운 데이터 추가
- StandardOpenOption.APPEND : 기존 데이터 보존하며 추가
- StandardOpenOption.WRITE : 기존 데이터에 새로운 값을 덮어쓰기
- StandardOpenOption.CREATE : 해당 경로에 같은 파일명이 없을 경우 파일을 생성
- StandardOpenOption.DELETE_ON_CLOSE : 파일 삭제 Files.copy에서 사용하는 옵션 //io에는 이런거 없음 nio에만 있음
- StandardOpenOption.REPLACE_EXISTING : 파일 복제
- StandardOpenOption.CREATE_NEW : 새로운 파일을 생성하여 데이터를 추가
7. 파일 복제
- ASCII 형태의 파일 복사하는 형태
1. 생성할 파일을 제작해야함 (경로에 해당 파일이 있어야함)
2. 원본파일과 복사할 파일을 로드하여 데이터를 복사시킴
io + nio 끔찍한 혼종
package io;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
//io + nio 끔찍한 혼종 예제
public class file10 {
public static void main(String[] args) {
//복사할 파일을 생성
//File => 디렉토리 설정 => createNewFile() => 기존 데이터를 복사할 파일 이관
//io + nio => Spring같은거에서 에러나버림 그래서 io많이 사용
String ori = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree.txt";
String ori_copy = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree2.txt";
File f1 = new File(ori); //io
File f2 = new File(ori_copy);
try {
// f2.createNewFile(); //io여서 try catch 필요
//nio (Files)
// Files.copy(f1.toPath(), f2.toPath(), StandardCopyOption.REPLACE_EXISTING);
//----------------------------------------------//
//io(RandomAccessFiles(부모) - interface)
//r : read(읽기), w : write(쓰기), x : execution(실행)
//RandomAccessFiles(자식클래스) : 해당 파일 권한에 맞춰서 쓰기, 읽기 설정하는 클래스
RandomAccessFile f3 = new RandomAccessFile(ori,"r");
RandomAccessFile f4 = new RandomAccessFile(ori_copy, "rw");
//----------------------------------------------//
//FileChannel : nio 클래스(파일 읽기, 쓰기, 맵핑)
FileChannel fc = f3.getChannel();
System.out.println(fc.size()); //byte 크기 (파일 용량) //자료형과 다름
FileChannel fc2 = f4.getChannel();
fc.transferTo(0, fc.size(), fc2);
}catch(Exception e) {
System.out.println("경로 및 파일명 오류 발생!");
}
}
}
io 전용 파일 복사 방식 (Stream (X)) - ASCII 전용
package io;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
//io 전용 파일 복사 방식 (Stream (X)) - ASCII 전용
//FileReader, FileWriter
public class file11 {
public static void main(String[] args) {
//원본파일
String ori = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree2.txt";
//사본파일
String copyfile = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/agree3.txt";
try {
File f1 = new File(ori); //원본 경로 파일
File f2 = new File(copyfile); //사본 경로 파일
boolean result = f2.createNewFile(); //사본 파일을 해당 경로 생성
//원본 파일의 내용을 읽는 코드
System.out.println(result);
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);//읽은 내용을 모두 메모리에 등록
//이 경우는 버퍼에 있는걸 사용하는게 아니고 그저 복사하는거라서 배열을 사용하지 않아도 됨
//사본 파일에 원본 파일 내용을 입력하기 위한 선언문
FileWriter fw = new FileWriter(f2, true); //기존 내용 유지
String data = ""; //임시 메모리에 있는 내용을 해당 변수로 받기 위해 생성
while((data = br.readLine()) != null) { //임시 메모리의 값을 반복적으로 체크하며 값을 사본파일에 쓰기
fw.write(data+"\n");
}
//닫을땐 항상 역순
fw.close();
br.close();
fr.close();
}catch(Exception e) {
System.out.println("파일을 가져올 수 없습니다.");
}
}
}
😊응용문제
키오스크에서 오더 받은 내용을 다음과 같이 정리하여 order.txt로 저장되도록 하기
[결과]
메뉴를 고르세요 [1.아이스커피, 2.아메리카노, 3.카라멜마끼야또] :
아이스커피 : 2000원
아메리카노 : 3500원
카라멜 마끼야또 : 4000원
[order.txt 저장 내용]
신청하신 내용 : 아메리카노
결제 금액 : 3500
내 코드
package io;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class file12 {
public static void main(String[] args) {
file12_box fb = new file12_box();
}
}
class file12_box{
String list[][] = { { "아이스커피", "아메리카노", "카라멜 마끼야또" }, { "2000", "3500", "4000" } };
ArrayList<String> m = null;
ArrayList<ArrayList<String>> ml = null;
StringBuilder sb = null;
int mn = 0;
public file12_box() {
this.ml = new ArrayList<ArrayList<String>>();
int i = 0;
while (i < this.list.length) {
this.m = new ArrayList<String>(Arrays.asList(list[i]));
this.ml.add(this.m);
i++;
}
this.kiosk();
}
public void kiosk() {
this.menu();
try {
write_order();
} catch (Exception e) {
System.out.println("영수증 출력 실패");
new file12_box();
}
System.out.println("영수증 출력 완료");
}
private void menu() {
this.sb = new StringBuilder();
int i = 0;
while (i < this.ml.get(0).size()) {
this.sb.append((i + 1) + ". " + this.ml.get(0).get(i) + " : " + this.ml.get(1).get(i) + "원\n");
i++;
}
this.sb.append("메뉴를 고르세요 : ");
System.out.println(sb);
Scanner sc = new Scanner(System.in);
try {
this.mn = sc.nextInt();
} catch (Exception e) {
System.out.println("잘못된 입력");
new file12_box();
} finally {
sc.close();
}
}
private void write_order() throws Exception {
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/order.txt";
File odr = new File(url);
odr.createNewFile();
FileWriter fw = new FileWriter(url);
int n = this.mn - 1;
fw.write("신청하신 내용 : " + this.ml.get(0).get(n) + "\n결제 금액 : " + this.ml.get(1).get(n));
fw.close();
}
}
선생님 코드
package io;
import java.io.File;
import java.io.FileWriter;
import java.util.Scanner;
public class file12_t {
public static void main(String[] args) {
file12_tbox tb = new file12_tbox();
}
}
class file12_tbox{
final String data[][] = { { "아이스커피", "2000" }, { "아메리카노", "3500" }, { "카라멜 마끼야또", "4000" } }; //DB형태 {"hong","홍길동","hong@nate.com"}
Scanner sc = null;
FileWriter fw = null;
int menu; //변수만 선언
public file12_tbox() {
this.sc = new Scanner(System.in);
this.menulist();
}
private void menulist() { //메뉴 리스트 출력 및 메뉴를 선택
String menus = ""; //사용자에게 메뉴를 보여주는 형태
for(int f = 0;f<this.data.length;f++) {
menus += this.data[f][0] + " " ;
}
System.out.printf("메뉴를 고르세요 [%s] : ", menus);
try {
this.menu = this.sc.nextInt();
if(this.menu > 0 && this.menu < 4) {
String result = this.receipt();
if(result=="ok") {
System.out.println("정상적으로 주문이 완료되었습니다.");
}else {
System.out.println("서비스 장애로 다시 주문 부탁드립니다.");
}
}else {
System.out.println("1~3번까지의 메뉴를 선택하셔야합니다.");
file12_tbox(); //new file12_box(); 이것도 가능 //요줄 왜 오류나지?
}
}catch(Exception e) { //메뉴 선택에 대한 숫자외 다른 문자 입력시
System.out.println("1~3번까지의 숫자를 입력하세요.");
new file12_tbox(); //클래스 다시실행 (menulist 메소드를 재귀하는건 오류남)
}finally {
this.sc.close();
}
}
//파일에 사용자가 선택한 메뉴 관련 정보를 저장하는 메소드
private String receipt() {
String call = "no"; //해당 데이터를 올바르게 진행 겷과를 return하는 변수
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/order.txt";
try { //정상적으로 해당 파일에 데이터가 저장되었을 경우
File f = new File(url);
boolean check = f.createNewFile(); //파일신규생성(true) , 같은파일존재(false)->기존파일삭제 //이런코드추가하면 좋음
this.fw = new FileWriter(f);
this.fw.write("신청하신 메뉴 : " + this.data[this.menu-1][0] + "\n");
this.fw.write("결제 금액 : " + this.data[this.menu-1][1] + "원");
call = "ok";
}catch(Exception e) { //io문제가 발생 시
System.out.println("해당 파일을 로드하지 못하였습니다.");
}finally { //IO를 종료하는 파트
try { //FileWriter를 종료 (IO니까 try를 또 써야함!)
this.fw.close();
}catch(Exception e) {
System.out.println("해당 파일을 정상적으로 종료하지 못하였습니다.");
}
}
return call;
}
}
8. ASCII 주의사항
package io;
import java.io.File;
import java.io.FileWriter;
import java.util.Scanner;
public class file13 {
public static void main(String[] args) {
try{
String url = "/Users/nayeong/Documents/Eclipse/basic_html/src/main/java/io/test.txt";
File fe = new File(url); //해당 파일이 존재하면 이거 안써도됨
fe.createNewFile(); //이거도
FileWriter fw = new FileWriter(url);
Scanner sc = new Scanner(System.in);
System.out.println("숫자를 입력하세요 : ");
// int user = sc.nextInt(); //=> (String)user 로 사용
String user = sc.next();
fw.write(user);
sc.close();
fw.close();
}catch(Exception e) {
System.out.println("파일 경로 오류!");
}
}
}
- write를 쓸 때 자료형이 문자자료형이 아니면 오류 발생
- 다른자료형 쓰고싶으면 자료형 변환해서 사용