<명품 JAVA Programming> - Chapter8 실습문제

목차

1. Scanner로 입력받은 이름과 전화번호를 한 줄에 한 사람씩 c:\temp\phone.txt 파일에 저장할. "그만"을 입력하면 프로그램을 종료한다.

package chapter8;
import java.io.*;
import java.util.Scanner;

public class Q1 {
	public static void main(String[] args) {
		System.out.println("전화번호 입력 프로그램입니다.");
		Scanner sc = new Scanner(System.in);
		String name, phoneNumber;
		FileWriter fout = null;
		
		try {
			fout = new FileWriter("c:\\Temp\\phone.txt");
			while(true) {
				name = sc.next();
				if(name.equals("그만")) break;
				phoneNumber = sc.next();
				
				fout.write(name);
				fout.write(" " + phoneNumber);
				fout.write("\r\n");
			}
			fout.close();
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}
		
		sc.close();
	}
}

 

2. 앞서 저장한 c:\temp\phone.txt 파일을 읽어 화면에 출력하라.

package chapter8;
import java.io.*;

public class Q2 {
	public static void main(String[] args) {
		System.out.println("c:\\Temp\\phone.txt를 출력합니다.");
		FileReader fin = null;
		int c;
		
		try {
			fin = new FileReader("c:\\Temp\\phone.txt");
			while((c = fin.read()) != -1) {
				System.out.print((char)c);
			}
			fin.close();
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}
	}
}

 

 

3. c:\windows\system.ini 파일을 읽어 소문자를 모두 대문자로 바꾸어 출력하라.

package chapter8;
import java.io.*;

public class Q3 {
	public static void main(String[] args) {
		FileReader fin = null;
		int c;
		
		try {
			fin = new FileReader("c:\\windows\\system.ini");
			while((c = fin.read()) != -1) {
				c = Character.toUpperCase(c);
				System.out.print((char)c);
			}
			fin.close();
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}
	}
}

 

 

4. c:\windows\system.ini 파일에 라인 번호를 붙여 출력하라.

package chapter8;
import java.io.*;
import java.util.Scanner;

public class Q4 {
	public static void main(String[] args) {
		System.out.println("c:\\windows\\system.ini를 읽어 출력합니다.");
		FileReader fin = null;
		int i = 1;		//줄 번호
		
		try {
			fin = new FileReader("c:\\windows\\system.ini");
			/*BufferedReader로 한 줄 읽기
			BufferedReader br = new BufferedReader(fin);
			String line = "";
			while((line = br.readLine()) != null) {
				System.out.printf("%2d: ", i);
				System.out.println(line);
				i++;
			}
			br.close(); */
			//Scanner로 한 줄 읽기
			Scanner fScanner = new Scanner(fin);
			while(fScanner.hasNext()) {
				String line = fScanner.nextLine();
				System.out.printf("%2d: ", i);
				System.out.println(line);
				i++;
			}
			fin.close();
			fScanner.close();
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}
	}
}

5. 2개의 파일을 입력받고 비교하여 같으면 "파일이 같습니다.", 틀리면 "파일이 서로 다릅니다."를 출력하는 프로그램을 작성하라. 텍스트 및 바이너리 파일 모두를 포함한다. 아래 실행 예시에서는 프로젝트 폴더에 elvis1.txt와 복사본 elvis1-복사본.txt를 미리 준비해 두었다.

package chapter8;
import java.io.*;
import java.util.Scanner;

public class Q5 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		FileInputStream one = null;
		FileInputStream two = null;
		System.out.println("전체 경로명이 아닌 파일 이름만 입력하는 경우, 파일은 프로젝트 폴더에 있어야 합니다.");
		
		System.out.print("첫 번째 파일 이름을 입력하세요>>");
		String first = sc.next();
		System.out.print("두 번째 파일 이름을 입력하세요>>");
		String second = sc.next();
		
		System.out.println(first + "와 " + second + "를 비교합니다.");
		try {
			one = new FileInputStream(first);
			two = new FileInputStream(second);
			if(compareFile(one, two))
				System.out.println("파일이 같습니다.");
			else
				System.out.println("파일이 다릅니다.");
			
			one.close();
			two.close();
		} catch(IOException e) {
			System.out.println("입출력 오류가 발생했습니다.");
		}
		sc.close();
	}
	
	private static boolean compareFile(FileInputStream one, FileInputStream two) throws IOException {
		byte[] buf1 = new byte[1024];	//버퍼
		byte[] buf2 = new byte[1024];
		
		int count1 = 0, count2;
		while(true) {
			count1 = one.read(buf1, 0, buf1.length);	//버퍼 크기만큼 읽어서
			count2 = two.read(buf2, 0, buf2.length);
			
			if(count1 != count2) return false;			//크기가 다르면 파일이 다름
			if(count1 == -1) break;						//끝에 도달
			
			for(int i = 0; i < count1; i++) {			//각각 비교
				if(buf1[i] != buf2[i]) return false;
			}
		}
		return true;
	}
}

 

 

6. 사용자로부터 두 개의 텍스트 파일 이름을 입력받고 첫 번째 파일 뒤에 두 번째 파일을 덧붙인 새로운 파일을 생성하는 프로그램을 작성하라. 아래 실행 예시에서는 프로젝트 폴더에 elvis1.txt와 elvis2.txt를 미리 준비해 두었다.

package chapter8;
import java.io.*;
import java.util.Scanner;

public class Q6 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		FileInputStream src = null;
		FileInputStream dst = null;
		FileOutputStream app = null; 
		System.out.println("전체 경로명이 아닌 파일 이름만 입력하는 경우, 파일은 프로젝트 폴더에 있어야 합니다.");
		
		System.out.print("첫 번째 파일 이름을 입력하세요>>");
		String first = sc.next();
		System.out.print("두 번째 파일 이름을 입력하세요>>");
		String second = sc.next();

		try {
			src = new FileInputStream(first);
			dst = new FileInputStream(second);
			app = new FileOutputStream("append.txt");
			byte [] buf = new byte [1024*10];
			byte [] buf2 = new byte [1024*10];
			while(true) {
				int n = src.read(buf);
				app.write(buf, 0, n);
				if(n < buf.length) break;	//버퍼 크기보다 작음 -> 파일 끝 
			}
			while(true) {
				int n = dst.read(buf2);
				app.write(buf2, 0, n);
				if(n < buf2.length) break; 
			}
			src.close();
			dst.close();
			app.close();
			System.out.println("프로젝트 폴더 밑에 append.txt. 파일에 저장했습니다.");
		} catch(IOException e) {
			System.out.println("입출력 오류가 발생했습니다.");
		}
		sc.close();
	}
}

 

 

7. 파일 복사 연습을 해보자. 이미지 복사가 진행되는 동안 10% 진행할 때마다 '*'을 하나씩 출력하도록 하라. 아래 실행 예시에서는 프로젝트 폴더 밑에 a.jpg을 미리 준비해 두었다.

package chapter8;
import java.io.*;

public class Q7 {
	public static void main(String[] args) {
		BufferedInputStream srcStream = null;
		BufferedOutputStream destStream = null;
		File srcFile = new File("a.jpg");
		File destFile = new File("b.jpg");

		System.out.print("a.jpg를 b.jpg로 복사합니다.\n10%마다 *를 출력합니다.");

		try {
			srcStream = new BufferedInputStream(new FileInputStream(srcFile)); // 버퍼 입력 스트림에 연결
			destStream = new BufferedOutputStream(new FileOutputStream(destFile)); // 버퍼 출력 스트림에 연결
			long tenPercent = srcFile.length() / 10; // 파일의 10% 크기
			long progress = 0; // 파일 크기 10% 될 때까지 읽은 누적 바이트 수
			byte [] buf = new byte [1024];

			int numRead = 0; // 읽은 바이트 수 
			while (true) {
				numRead = srcStream.read(buf, 0, buf.length);
				if(numRead == -1) { // 파일 끝에 도달함
					if(progress > 0) { // 지난번에 읽었지만 10%에 도달하지 않아 *가 출력되지 않은 경우
						System.out.print("*");
					}
					break; // 파일 끝에 도달함
				}
				if (numRead > 0)
					destStream.write(buf, 0, numRead);
				
				progress += numRead; // 파일 크기 10% 될 때까지 읽은 누적 바이트 수
				if (progress >= tenPercent) { // 10% 만큼 읽었다면
					System.out.print("*");
					progress = 0; // * 출력하고 progress를 0으로 리셋
				}
			}
           	srcStream.close();
           	destStream.close();
		}catch(IOException e) {
			System.out.println("입출력 오류가 발생했습니다.");
		}
	}
}

 

 

8. File 클래스를 이용하여 c:\에 있는 파일 중에서 제일 큰 파일의 이름과 크기를 출력하라.

package chapter8;
import java.io.File;

public class Q8 {
	public static void main(String[] args) {
		File f = new File("C:\\");
		File [] subFiles = f.listFiles();
		long max = 0;
		String name = "";
		for(int i = 0; i < subFiles.length; i++) {
			File temp = subFiles[i];
			if (max < temp.length()) {
				max = temp.length();
				name = temp.getName();
			}
		}
		System.out.println("가장 큰 파일은 " + name + " " + max + "바이트");
	}
}

 

 

9. c:\temp에 있는 .txt파일만 삭제하는 프로그램을 작성하라. c:\나 c:\Windows 등의 디렉터리에 적용하면 중요한 파일이 삭제될 수 있으니 조심하라.

package chapter8;
import java.io.File;

public class Q9 {
	public static void main(String[] args) {
		File f = new File("C:\\Temp\\tempTxt");
		File [] subFiles = f.listFiles();
		int count = 0;
		for(int i = 0; i < subFiles.length; i++) {
			String name = subFiles[i].getName();
			int index = name.lastIndexOf(".txt");
			if(index != -1) {
				subFiles[i].delete();
				System.out.println(name + "삭제");
				count++;
			}
		}
		System.out.println("총 " + count + "개의 .txt 파일을 삭제 했습니다.");
	}
}

 

 

10. 전화번호를 미리 c:\temp\phone.txt 파일에 여러 개 저장해둔다. 이 파일을 읽어 다음 실행 예시와 같이 동작하는 검색 프로그램을 작성하라.

package chapter8;
import java.io.*;
import java.util.*;

public class Q10 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, String> phone = new HashMap<String, String>();
		try {
			Scanner fScanner = new Scanner(new FileReader("C:\\Temp\\phone.txt"));
			while(fScanner.hasNext()) {
				String line = fScanner.nextLine();	//한 줄을 읽고
				String s[] = line.split(" ");	//이름과 전화번호 분리
				phone.put(s[0], s[1]);
			}
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}
		
		System.out.println("총 " + phone.size() + "개의 전화번호를 읽었습니다.");
		while(true) {
			System.out.print("이름>>");
			String name = sc.next();
			if(name.equals("그만")) break;
			if(phone.containsKey(name))
				System.out.println(phone.get(name));
			else
				System.out.println("찾는 이름이 없습니다.");
		}
		sc.close();
	}
}

 

 

11. words.txt 파일에는 한 라인에 하나의 영어 단어가 들어 있다. 이 파일을 한 라인씩 읽어 Vector<String>에 라인별로 삽입하여 저장하고, 영어 단어를 입력받아 그 단어로 시작하는 모든 단어를 벡터에서 찾아 출력하는 프로그램을 작성하라.

package chapter8;
import java.io.*;
import java.util.*;

public class Q11 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Vector<String> wordsV = new Vector<String>();
		try {
			Scanner fScanner = new Scanner(new FileReader("C:\\Temp\\words.txt"));
			while(fScanner.hasNext()) {
				String line = fScanner.nextLine();	//한 줄을 읽고
				wordsV.add(line);
			}
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}

		System.out.println("프로젝트 폴더 밑의 words.txt 파일을 읽었습니다...");
		
		while(true) {
			boolean check = false;
			
			System.out.print("단어>>");
			String word = sc.next();
			if(word.equals("그만")) {
				System.out.println("종료합니다."); break;
			}
			
			Iterator<String> it = wordsV.iterator();
			while(it.hasNext()) {
				String temp = it.next();
				if(temp.length() < word.length()) continue;	//벡터 내 문자열이 더 짧을 때
				String frontPart = temp.substring(0, word.length());
				if(word.equals(frontPart)) {
					System.out.println(temp);
					check = true;
				}
			}
			if(!check) System.out.println("발견할 수 없음");
		}
		sc.close();
	}
}

 

 

12. 텍스트 파일에 있는 단어를 검색하는 프로그램을 작성해보자. 실행 예시는 프로젝트 폴더 밑에 자신이 작성한 자바 파일을 복사하여 두고 읽은 경우이다.

package chapter8;
import java.io.*;
import java.util.*;

public class Q12 {
	public static void main(String[] args) {
		Vector<String> lineVector = new Vector<String>();
		Scanner sc = new Scanner(System.in);

		System.out.println("전체 경로명이 아닌 파일 이름만 입력하는 경우, 파일은 프로젝트 폴더에 있어야 합니다.");
		System.out.print("대상 파일명 입력>>");
		String filename = sc.next();

		try {
			Scanner fScanner = new Scanner(new FileReader(filename));
			while(fScanner.hasNext()) {
				String line = fScanner.nextLine();	//한 줄을 읽고
				lineVector.add(line);
			}
		} catch(IOException e) {
			System.out.println("입출력 오류");
		}

		while(true) {
			System.out.print("검색할 단어나 문장>>");
			String search = sc.next();
			if(search.equals("그만")) {
				System.out.println("프로그램을 종료합니다.");
				break;
			}

			Iterator<String> it = lineVector.iterator();
			while(it.hasNext()) {
				String temp = it.next();
				if (temp.contains(search))
					System.out.println(temp);
			}
		}
		sc.close();
	}
}

 

 

13. 간단한 파일 탐색기를 만들어보자. 처음 시작은 c:\에서부터 시작한다. 명령은 크게 2가지로서 ".."를 입력하면 부모 디렉터리로 이동하고, "디렉터리명"을 입력하면 서브 디렉터리로 이동하여 파일 리스트를 보여준다.

package chapter8;
import java.util.*;
import java.io.File;

public class Q13 {
	public static void main(String[] args) {
		System.out.println("****파일 탐색기입니다****");
		Scanner sc = new Scanner(System.in);

		File file = new File("c:\\");

		while(true) {
			File subFiles[] = file.listFiles();
			System.out.println("[" + file.getPath() + "]");

			for(int i = 0; i < subFiles.length; i++) {
				String res="";
				File f = subFiles[i];
				if(f.isFile()) res = "file";
				else if(f.isDirectory()) res = "dir";

				System.out.print(res + "\t");
				System.out.printf("%-10s바이트\t\t", f.length());
				System.out.printf("%s\n", f.getName().trim());
			}

			System.out.print(">>");
			String dir = sc.next();
			String newDir = "";
			if(dir.equals("그만")) break;
			if(dir.equals(".."))
				newDir = file.getParent();	//상위 디렉토리로 이동
			else
				newDir = file.getPath().concat("\\" + dir);	//하위 디렉토리로 이동
			file = new File(newDir);
		}
		sc.close();
	}
}

 

14. 문제 13을 확장하여 다음 명령을 추가하라.

rename phone.txt p.txt // phone.txt를 p.txt로 변경. 파일과 디렉터리 이름 변경
mkdir XXX // 현재 디렉터리 밑에 XXX 디렉터리 생성
package chapter8;
import java.util.*;
import java.io.File;

public class Q13 {
	public static void main(String[] args) {
		System.out.println("****파일 탐색기입니다****");
		Scanner sc = new Scanner(System.in);

		File file = new File("c:\\");

		while(true) {
			File subFiles[] = file.listFiles();
			System.out.println("[" + file.getPath() + "]");

			for(int i = 0; i < subFiles.length; i++) {
				String res="";
				File f = subFiles[i];
				if(f.isFile()) res = "file";
				else if(f.isDirectory()) res = "dir";

				System.out.print(res + "\t");
				System.out.printf("%-10s바이트\t\t", f.length());
				System.out.printf("%s\n", f.getName().trim());
			}

			System.out.print(">>");
			String dir = sc.nextLine();
			try {
				StringTokenizer st = new StringTokenizer(dir);
				String newDir = file.getPath();
				
				if(st.countTokens() == 1) {
					if(dir.equals("그만")) break;
					if(dir.equals(".."))
						newDir = file.getParent();	//상위 디렉토리로 이동
					else
						newDir = file.getPath().concat("\\" + dir);	//하위 디렉토리로 이동
				}
				else {
					//분리된 토큰에 이름을 붙인다
					String operation = st.nextToken();
					String name = st.nextToken();
					//명령(첫 번째 토큰)이 mkdir일 때
					if (operation.equals("mkdir")) {
						File f = new File(file.getPath().concat("\\" + name));
						f.mkdir();
						System.out.println(name + "디렉토리를 생성했습니다.");
					}
					//명령이 rename일 때
					else if(operation.equals("rename")) {
						String dest = st.nextToken();
						File f = new File(file.getPath().concat("\\" + name));
						f.renameTo(new File(file.getPath().concat("\\" + dest)));
						System.out.println("파일명을 변경했습니다.");
					}
				}
				file = new File(newDir);
			}
			catch (NoSuchElementException e) {
				System.out.println("두 개의 파일명이 주어지지 않았습니다!");
			}
		}
		sc.close();
	}
}