자바칩
[자바의 신] 26장. I/O: 문제 풀이 본문
728x90
정리해 봅시다
1. I/O는 각각 무엇의 약자인가요?
Input/Output
I/O는 JVM을 기준으로 읽을 때에는 Input을, 파일로 쓰거나 외부로 전송할 때에는 Output이라는 용어를 사용한다.
2. File 클래스는 파일만 지정할 수 있나요?
파일뿐만 아니라, 파일의 경로도 지정할 수 있다.
3. OS마다 다른 경로 구분자를 처리하기 위해서는 File 클래스의 어떤 상수를 사용해야 하나요?
separator (static 상수)
*사용 예시1
import java.io.File;
String filePath1 = "C:\\godofjava\\text";
String filePath2 = File.separator + "godofjava" + File.separator + "text"; // filePath1와 같은 경로
*사용 예시2
import static java.io.File.separator;
String filePath1 = "C:\\godofjava\\text";
String filePath2 = separator + "godofjava" + separator + "text"; // filePath1와 같은 경로
4. File 클래스에서 디렉터리를 만드는 mkdir()과 mkdirs() 메소드의 차이는 무엇인가요?
메소드 | 차이점 |
mkdir() | 하위 디렉터리를 1개만 생성 가능 |
mkdirs() | 하위 디렉터리를 여러 개 생성 가능 |
5. File 클래스의 list() 메소드와 listFiles() 메소드의 차이는 무엇인가요?
메소드 | 차이점 |
list() | 현재 디렉터리의 하위에 있는 목록을 String 배열로 리턴 |
listFiles() | 현재 디렉터리의 하위에 있는 목록을 File 배열로 리턴 |
6. FileFilter와 FilenameFilter의 차이는 무엇인가요?
인터페이스 | 차이점 |
FileFilter | 선언된 메소드: accept(File file) 매개 변수로 넘어온 File 객체가 조건에 맞는지 확인한다. File 객체의 getName()으로 파일 이름을 얻어와서 대상에 포함되는 파일을 선택해야 한다. |
FilenameFilter | 선언된 메소드: accept(File file, String name) 매개 변수로 넘어온 디렉터리(dir)에 있는 경로나 파일 이름(name)이 조건에 맞는지 확인한다. File 객체의 getName()으로 파일 이름을 얻어올 필요 없이, 두 번째 매개변수인 파일 이름(name)을 바로 사용하면 된다. |
FileFliter와 FilenameFilter를 사용해서 확장자가 jpg인 이미지만 가져오려고 하는 코드는 다음과 같다.
*FileFilter 사용 예시
public class JPGFileFilter implements FileFilter {
@Override
public boolean accpet(File file) { // FileFilter에 선언된 메소드 구현
if (file.isFile()) { // File 객체가 파일인지 판단
String fileName = file.getName(); // File 객체로 파일 이름 얻어오기
if (fileName.endsWith(".jpg")) return true; // 파일 이름이 .jpg로 끝나면 true 리턴
}
return false; // 그 외의 경우는 모두 false 리턴
}
}
*FilenameFilter 사용 예시
public class JPGFilenameFilter implements FilenameFilter {
@Override
public boolean accept(File file, String fileName) { // FilenameFilter에 선언된 메소드 구현
if (fileName.endsWith(".jpg")) return true; // 파일 이름이 .jpg로 끝나면 true 리턴
return false; // 그 외의 경우는 모두 false 리턴
}
}
FilenameFilter가 FileFilter에 비해 과정이 조금 더 간단하지만, 파일 이름만으로는 디렉터리와 파일을 구분하지 못한다. 확장자가 jpg인 이미지만 가져오려고 했는데, .jpg로 끝나는 디렉터리가 있으면 이것까지 같이 가져온다. 즉, 필터로 올바르게 걸러낼 수가 없다.
7. InputStream이라는 abstract 클래스는 어떤 작업을 하기 위해서 만들어진 것인가요?
바이트 코드를 읽는 작업을 하기 위해서 만들어졌다.
8. OutputStream이라는 abstract 클래스는 어떤 작업을 하기 위해서 만들어진 것인가요?
바이트 코드를 쓰는 작업을 하기 위해서 만들어졌다.
9. Reader라는 abstract 클래스는 어떤 작업을 하기 위해서 만들어진 것인가요?
char나 문자열 데이터를 읽는 작업을 하기 위해서 만들어졌다.
10. Writer라는 abstract 클래스는 어떤 작업을 하기 위해서 만들어진 것인가요?
char나 문자열 데이터를 쓰는 작업을 하기 위해서 만들어졌다.
I/O 클래스 | 역할 |
InputStream | 바이트 코드를 읽는 작업을 한다. |
OutputStream | 바이트 코드를 쓰는 작업을 한다. |
Reader | char나 문자열 데이터를 읽는 작업을 한다. |
Writer | char나 문자열 데이터를 쓰는 작업을 한다. |
11. BufferedReader나 BufferedWriter를 사용하는 이유는 무엇인가요?
Reader 클래스의 read() 메소드, Writer 클래스의 write()나 append() 메소드를 사용하여 데이터를 쓰면, 메소드를 호출했을 때마다 파일에 읽거나 쓰는 작업을 하게 되어 매우 비효율적이다. 이러한 단점을 보완하기 위해 BufferedReader나 BufferedWriter를 사용하면 된다. BufferedReader는 버퍼라는 공간에 읽을 데이터를 보관해 두었다가, 버퍼가 차게 되면 데이터를 읽어오도록 도와주고, BufferedWriter는 버퍼라는 공간에 저장할 데이터를 보관해 두었다가, 버퍼가 차게 되면 데이터를 저장하도록 도와준다.
I/O 클래스 | 차이점 |
Reader | read() 메소드를 호출할 때마다 파일에서 데이터를 읽어온다. |
Writer | write()나 append() 메소드를 호출할 때마다 파일에 데이터를 저장한다. |
BufferedReader | 버퍼라는 공간에 읽을 데이터를 보관해 두었다가, 버퍼가 차게 되면 데이터를 읽어오도록 도와준다. |
BufferedWriter | 버퍼라는 공간에 저장할 데이터를 보관해 두었다가, 버퍼가 차게 되면 데이터를 저장하도록 도와준다. |
12. 파일을 읽고, 문자열을 처리하기 위해서 필요한 Scanner 클래스가 속해있는 패키지는 무엇인가요?
java.util 패키지
직접해 봅시다
package e.io.practice; // 1번
import java.io.File; // 2번
import java.text.DecimalFormat; // 5번
public class FileSizeSummary { // 1번
// 1번
public static void main(String[] args) {
FileSizeSummary sample = new FileSizeSummary();
String path = "C:\\godofjava";
long sum = sample.printFileSize(path);
System.out.println(path + "'s total size = " + sum);
}
// 2, 3번
public long printFileSize(String dirName) {
long totalFileSize = 0;
File dir = new File(dirName);
if (dir.isDirectory()) {
File[] fileList = dir.listFiles();
for (File file : fileList) {
if (file.isFile()) {
String tempFileName = file.getAbsolutePath();
long fileLength = file.length();
System.out.println(tempFileName + " = " + convertFileLength(fileLength)); // 4, 5번
totalFileSize += fileLength;
} else {
String tempDirName = file.getAbsolutePath();
long dirLength = printFileSize(tempDirName);
System.out.println("[" + tempDirName + "] = " + convertFileLength(dirLength)); // 4, 5번
totalFileSize += dirLength;
}
}
}
return totalFileSize;
}
// 4번
private String convertFileLength(long fileLength) {
DecimalFormat df = new DecimalFormat("#.##"); // 5번
if (fileLength >= 0 && fileLength <= 1024) {
return fileLength + " b";
} else if (fileLength <= 1024 * 1024) {
return df.format(1.0 * fileLength / 1024) + " kb"; // 5번
} else if (fileLength <= 1024 * 1024 * 1024) {
return df.format(1.0 * fileLength / (1024 * 1024)) + " mb"; // 5번
} else {
return df.format(1.0 * fileLength / (1024 * 1024 * 1024)) + " gb"; // 5번
}
}
}
'Study > Java' 카테고리의 다른 글
[자바의 신] 28장. Socket과 Datagram: 문제 풀이 (0) | 2024.05.29 |
---|---|
[자바의 신] 27장. Serializable과 NIO: 문제 풀이 (0) | 2024.05.26 |
[자바의 신] 25장. 쓰레드 (Thread): 문제 풀이 (0) | 2024.05.23 |
[Java] 상속과 조합 (0) | 2024.05.20 |
[Java] 가비지 컬렉션 (GC) (0) | 2024.05.19 |