21일차(3)/java(30) : Input, Output(2)
MainClass07
- 파일시스템 접근하기
package test.main;
import java.io.File;
public class MainClass07 {
public static void main(String[] args) {
// c:/를 Access 할 수 있는 파일 객체 생성
File f=new File("c:/");
String[] names=f.list();
//배열에 들어있는 문자열 모두 출력하기
for(int i=0; i<names.length; i++) {
String tmp=names[i];
System.out.println(tmp);
}
System.out.println("---------------");
for(String tmp:names) {
System.out.println(tmp);
}
}
}
- File. 으로 사용할 수 있는 파일에 관련된 객체들이 매우 많다!
.list();
- C:/ 에 들어있는 파일, 폴더 등의 이름을 배열에 넣어서 하나씩 다 출력하기!
- for문으로 계속 돌면서 총 파일/폴더 갯수만큼 반복한다.
- 확장 for문으로도 작성
- file객체의 list라는 메소드는 파일시스템 안에 들어있는 내용을 배열에 넣어 출력하는 기능
MainClass08
- 파일시스템 접근해서 목록 읽어오기
package test.main;
import java.io.File;
public class MainClass08 {
public static void main(String[] args) {
File f=new File("c:/");
//파일객체 목록(file[])을 얻어내기
File[] files=f.listFiles();
for(File tmp:files) {
if(tmp.isDirectory()) {
//대괄호를 디렉토리명 양쪽에 출력하기
System.out.println("[ "+tmp.getName()+" ]");
}else {
//파일이면 파일명만 출력
System.out.println(tmp.getName());
}
}
}
}
.listFiles();
- access할 수 있는 파일객체를 생성해서 배열에 담아서 리턴한다.
단순히 이름만 리턴하는것이 아니라!
.isDirectory() : 호출하면 이게 디렉토리인지 파일인지 알 수 있다.(boolean 값 리턴)
.getName() : 파일의 이름을 얻어낼 수 있다.
- 아까와는 다른 모양으로 출력되는데, 디렉토리와 파일이 구분된다.
MainClass09
- 파일시스템 접근해서 파일 생성/삭제
package test.main;
import java.io.File;
import java.io.IOException;
public class MainClass09 {
public static void main(String[] args) {
//이미 존재하거나 혹은 만들 예정인 파일을 제어할 수 있는 File 객체 생성
File f1=new File("C:/acorn202210/myFolder/sy.txt");
try {
//만약 해당 파일이 존재하지 않으면
if(!f1.exists()) {
f1.createNewFile();
System.out.println("sy.txt파일을 만들었습니다.");
}else {
f1.delete();
System.out.println("sy.txt파일을 삭제했습니다.");
}
}catch(IOException ie) {
ie.printStackTrace();
}
}
}
.createNewFile(); : 신규파일생성
.delete(); : 파일 삭제
- if문을 사용해 파일이 있으면 삭제하고, 없으면 생성한다.
- 예외처리 try문 안에 넣어 예외발생시에 대처!
MainClass10
- 파일시스템 접근해서 폴더 생성/삭제
package test.main;
import java.io.File;
public class MainClass10 {
public static void main(String[] args) {
File f1=new File("C:/acorn202210/myFolder/folder1");
//폴더 만들기
f1.mkdir();
for(int i=0; i<20; i++) {
File tmp=new File("C:/acorn202210/myFolder/folder"+i);
//tmp.mkdir(); //폴더 만들기
tmp.delete(); //폴더 삭제하기
}
}
}
.mkdir(); : 폴더 생성하기. make directory
- 폴더를 1,000개 만들고싶다면... for 문 안에 넣으면 된다.
- 삭제도 동일하게 할 수 있다.
- 주의 : 파일 객체로 아무거나 삭제하면 안 된다! 파일 객체로 삭제하면 복구가 안 된다.
- 파일 객체는 특정 파일에 access할 수 있는 객체
MainClass11
- 파일시스템 접근해서 파일에 문자 출력하기
package test.main;
import java.io.File;
import java.io.FileWriter;
public class MainClass11 {
public static void main(String[] args) {
//문자열을 저장할 파일을 만들기 위한 File 객체
File memoFile=new File("C:/acorn202210/myFolder/memo.txt");
try {
//만일 파일이 존재하지 않으면
if(!memoFile.exists()) {
//파일을 만들고
memoFile.createNewFile();
}
//파일에 문자열을 출력할 수 있는 객체의 참조값 얻어내기
FileWriter pw=new FileWriter(memoFile, true);
pw.write("안녕");
pw.write("\r\n");
pw.write("하세요");
pw.write("\r\n");
pw.write("\t"); // \t는 tab 들여쓰기이다.
pw.write("반가워요\r\n");
pw.flush();
pw.close();
System.out.println("파일에 문자를 저장했습니다.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
if(!memoFile.exists()) {}
- 만일 메모파일이 존재하지 않으면, 이라고 읽는다.( ! 연산자에 익숙해지기)
- if문을 try{} 안에넣고 catch(Exception e) 로 모든 예외를 처리해버림
- 파일객체에는 문자열을 출력할 수 있는 기능이 없다.
FileWriter : 파일에 문자열을 기록하고 싶을 때 사용
- FileWriter에 String타입을 받아 기록하는 메소드가 있다.
- 생성자 중 파일객체를 인자로 사용하는 생성자 사용!
- memo.txt파일에 텍스트를 전달하여 출력한다.
- run 하고 파일 안에서 값이 들어가있는 것을 확인할 수 있다.
참고)
- 인자 하나짜리 FileWriter 생성자를 사용하면 기본값이 덮어쓰기 상태이다. 여러번 run 해도 문자열이 누적되지 않는다.
- file, boolean 타입 2가지를 인자로 갖는 생성자를 사용해 append모드로 하면(true),
기본 덮어쓰기 상태(false)인 것을 바꾸어, 기존의 문자열을 유지하면서 덧붙일 수도 있다.
- 개행기호, 탭을 사용해서 위와 같이 출력할 수 있다. 개행기호, 탭을 모두 인식한다.
- \t 는 tab을 가리킨다.
MainClass12
- 파일시스템 접근해서 파일에서 문자 읽어오기
package test.main;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
/*
* C:/acorn202210/myFolder/memo.txt 파일에 기록된 문자열을 읽어서
* 콘솔창에 출력해 보세요.
*
* -hint
* FileReader객체를 잘 활용해 보세요.
*/
public class MainClass12 {
public static void main(String[] args) {
//File객체
File memofile=new File("C:/acorn202210/myFolder/memo.txt");
try {
//파일에서 문자열을 읽어들일수 있는 객체 생성
FileReader fr=new FileReader(memofile);
//반복문 돌면서
while(true) {
//한글자씩 읽어들인다.
int code=fr.read();
//만일 더이상 읽을 문자가 없으면
if(code==-1) {
break; //반복문 탈출!
}
//코드값을 문자로 변환해서
char ch=(char)code;
//개행기호 없이 읽은 내용만 출력
System.out.print(ch);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 파일에서 메모리로 읽어들여서 콘솔로 출력하기!
- 파일에서 읽어들일 때는 new하는 것이고, 출력할 때는 system.out만 활용하면 된다.
- String type을 리턴하고 싶은데 String타입이 없다...
- read(); 메소드의 설명을 보면(좌측 노란색 창) 아래와 같다.
Returns: The character read, or -1 if the end of the stream has been reached
(한글자씩 읽어내고 전부 다 읽었을 때 더이상 읽을것이 없으면 -1을 리턴한다.)
- 몇 번이나 돌아야 되는지 모르므로 while문 사용!
- 읽어온 코드값이 -1이 되면 while문을 중단하도록 작성한다.
- 읽어서 콘솔에 출력한 모습. 개행기호도 전부 하나하나 읽어서 콘솔창으로 가져온 것이다.
- 디버그모드에서 하나씩 돌려보면 while → if → char → syso 행을 순서대로 읽어내는 것을 볼 수 있다.
- 코드가 -1이 되면 break; 에서 정지하고 밖으로 빠져나온다.
MainClass13
- 파일시스템에서 읽어오는 FileReader를 BufferedReader로 포장하기
package test.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
/*
* C:/acorn202210/myFolder/memo.txt 파일에 기록된 문자열을 읽어서
* 콘솔창에 출력해 보세요.
*
* -hint
* FileReader객체를 잘 활용해 보세요.
*/
public class MainClass13 {
public static void main(String[] args) {
//File객체
File memofile=new File("C:/acorn202210/myFolder/memo.txt");
try {
//파일에서 문자열을 읽어들일수 있는 객체 생성
FileReader fr=new FileReader(memofile);
BufferedReader br=new BufferedReader(fr);
//반복문 돌면서
while(true) {
//개행기호를 기준으로 한줄씩 읽어오기 때문에 개행기호는 읽어오지 않는다.
String line=br.readLine();
if(line==null) {
break;
}
//읽어낸 문자열 콘솔에 출력하기
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
- BufferedReader는 글자 단위가 아니라 줄 단위로 읽어온다.
- FileReader를 인자로 받는 BufferedReader 타입 변수 생성
.readLine : 데이터를 읽어내주는 메소드인데 String 타입!
- 참조값을 리턴해주는 메소드는 보통 더이상 읽을 문자열이 없을 때 null을 리턴한다.
- 개행기호를 기준으로 한줄씩 읽어오기 때문에 따로 개행기호는 읽어오지 않는다.
if(line==null) { break; }
- while안에 탈출조건이 null인 if문 작성!
MainClass14
- 입/출력 작업의 마무리작업 close 사용
package test.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
/*
* C:/acorn202210/myFolder/memo.txt 파일에 기록된 문자열을 읽어서
* 콘솔창에 출력해 보세요.
*
* -hint
* FileReader객체를 잘 활용해 보세요.
*/
public class MainClass14 {
public static void main(String[] args) {
//File객체
File memofile=new File("C:/acorn202210/myFolder/memo.txt");
//필요한 객체를 담을 지역변수를 미리 만들어준다.
FileReader fr=null;
BufferedReader br=null;
try {
//미리 만들어둔 지역변수에 참조값 대입하기
fr=new FileReader(memofile);
br=new BufferedReader(fr);
//반복문 돌면서
while(true) {
//개행기호를 기준으로 한줄씩 읽어오기 때문에 개행기호는 읽어오지 않는다.
String line=br.readLine();
if(line==null) {
break;
}
//읽어낸 문자열 콘솔에 출력하기
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//마무리작업을 해주어야 되는데...
try {
//닫는 작업은 열린 순서의 역순으로 하면 좋다.
if(br!=null)br.close();
if(fr!=null)fr.close();
}catch(Exception e){}
}
}
}
- 프로세스가 아주 잠깐 만들어졌다가 데이터를 읽어오고 사라진다.
- 하지만 만약 어플리케이션이 쭉 실행중이라면, 이런 입출력을 하는 기능들이 자리를 차지할 수 있다.
- fr, br 과 같은 작업은 사실 어떤 마무리(종료작업)를 해주어야 한다. (지금은 크게 상관없지만..)
.close : 객체를 종료하는 메소드
- 다 사용한 입출력하는 객체들은 사용하고 나서 닫아주어야 한다!
- 지속적으로 사용되는 어플리케이션이라면 남은 입출력 객체가 꾸준히 메모리를 점유해 문제를 발생시킬 수 있다.
- 마무리 작업을 해주어야 되는데... 어떤 이유때문에 마무리를 못할 가능성이 있다면 try~catch문으로.
- close는 보통 열린 순서의 역순으로 닫아준다.
- 저 위치에 close가 위치해 있으면, catch문으로 들어가버릴 경우에는 close 할 수 없다.
→ 무조건 실행이 보장되는 블럭에 들어있어야 한다.
- finally절로 위치를 옮겨주었더니 br, fr 지역변수가 참조되지 않는다...
- br,fr 객체 생성시 exception 발생 가능성이 있으므로 try문 바깥으로 뺄 수 없는데,
try문 안에서는 finally절에서 참조가 안 된다...
- try문 바깥에서 변수를 미리 만들고, 참조값은 나중에 넣는 방식으로 해결한다.(try문 안에서)
- finally블럭 안에 close를 넣었는데, 위에서 예외가 생긴 경우 br,fr이 null일 수도 있다.
그런 경우 br, fr를 제대로 close 할 수 없으므로 nullpointException이 발생하고,
finally절로 오더라도 FileReader(br,fr)를 close 하지 못할 상황이 생길 수 있다.
- finally절 안에 if문을 넣어 안전하게 마무리한다.
- nullPointException : 참조값이 없다는 뜻!
- java 코드가 이런 순서로 진행되는 경우가 많으니 기억하기!
1. try문에서 지역변수 만들기
2. 참조값은 try블럭 안에서 들어가고
3. 객체는 어떤 작업을 하고
4. 어떤 예외가 발생했건 관계없이 finally블럭에서 마무리 작업
'국비교육(22-23)' 카테고리의 다른 글
22일차(2)/java(31) : Input, Output(3) (1) | 2022.11.04 |
---|---|
22일차(1)/java 퀴즈 : input, output 활용 예제 (0) | 2022.11.04 |
21일차(2)/java(29) : Input, Output(1) (0) | 2022.11.04 |
21일차(1)/java(28) : Thread (0) | 2022.11.03 |
20일차(3)/java 퀴즈 : Frame객체로 계산기 만들기 (0) | 2022.11.02 |