본문 바로가기
개념

[JAVA의 정석] Chapter15_연습문제

by cook_code 2024. 12. 15.
 
 

[15-1] 커맨드라인으로부터 파일명과 숫자를 입력받아서, 입력받은 파일의 내용의 처음부터 입력받은 숫자만큼의 라인을 출력하는 프로그램(FileHead.java)을 작성하라.

[Hint] BufferedReader의 readLine( )을 사용하라.

 

C:\jdk1.8\work\ch15>java FileHead 10

USAGE: java FileHead 10 FILENAME

 

C:\jdk1.8\work\ch15>java FileHead 10 aaa

aaa은/는 디렉토리이거나, 존재하지 않는 파일입니다.

 

C:\jdk1.8\work\ch15>java FileHead 10 FileHead.java

1:import java.io.*;

2:

3:class FileHead

4:{

5: public static void main(String[] args)

6: {

7: try {

8: int line = Integer.parseInt(args[0]);

9: String fileName = args[1];

10:

 

import java.io.*;

public class FileHead {
    public static void main(String[] args) {
        if (args.length != 2) {
            System.out.println("USAGE: java FileHead <number_of_lines> <filename>");
            System.exit(0);
        }

        int numberOfLines = 0;
        try {
            numberOfLines = Integer.parseInt(args[0]);
        } catch (NumberFormatException e) {
            System.out.println("첫 번째 인자는 숫자여야 합니다.");
            System.exit(0);
        }

        String fileName = args[1];
        File file = new File(fileName);

        if (!file.exists() || file.isDirectory()) {
            System.out.println(fileName + "은/는 디렉토리이거나, 존재하지 않는 파일입니다.");
            System.exit(0);
        }

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            int count = 0;
            while ((line = br.readLine()) != null && count < numberOfLines) {
                System.out.println((count + 1) + ":" + line);
                count++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 

아니 왜 자꾸 이것만 뜨지?

Connected to the target VM, address: '127.0.0.1:50249', transport: 'socket'
USAGE: java FileHead <number_of_lines> <filename>
Disconnected from the target VM, address: '127.0.0.1:50249', transport: 'socket'

Process finished with exit code 0
 

읽을 파일이 없다는 건데 문제는 기존 자바 파일을 테스트하던 것처럼 디버깅 모드로 그냥 실행했기 때문이다.

문제에 나와있는 실행결과를 제대로 보면 알 수 있었음 ಥ_ಥ

 

로직 테스트 방법

1. 터미널을 열고 작업 중인 class 파일 폴더 열기 (cd 경로...)

2. java FileHead 3 C:\Users\catsp\Desktop\테스트할 파일명.txt

-> FileHead 메서드를 실행해서 파일의 3번째 줄까지 읽겠다. 해당 파일은 어쩌구 txt이다.

1:안녕하세요 
2:chapter15_1 파일 입출력 테스트
3:텍스트 파일입니다.
 

참고

인텔리제이 콘솔 깨짐


[15-2] 지정된 이진파일의 내용을 실행결과와 같이 16진수로 보여주는 프로그램(HexaViewer.java)을 작성하라.

[Hint]PrintStream과 printf( )를 사용하라.

 

C:\jdk1.8\work\ch15>java HexaViewer HexaViewer.class

CA FE BA BE 00 00 00 31 00 44 0A 00 0C 00 1E 09

00 1F 00 20 08 00 21 0A 00 08 00 22 0A 00 1F 00

23 07 00 24 0A 00 06 00 25 07 00 26 0A 00 08 00

27 0A 00 06 00 28 08 00 29 07 00 2A 0A 00 2B 00

2C 0A 00 08 00 2D 0A 00 08 00 2E 0A 00 06 00 2F

0A 00 08 00 2F 07 00 30 0A 00 12 00 31 07 00 32

01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01

00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D

62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E 01

00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53

 

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;

public class HexaViewer {
    public static void main(String[] args) throws IOException {
        // 입력 인자 검사
        if (args.length != 1) {
            System.out.println("USAGE: java HexaViewer FILENAME");
            System.exit(0);
        }

        String inputFile = args[0];

        // try-with-resources 구문을 사용하여 FileInputStream과 PrintStream을 자동으로 닫음
        try (FileInputStream input = new FileInputStream(inputFile);
             PrintStream output = System.out) {

            int data; // 파일로부터 읽어온 바이트를 저장할 변수
            int i = 0; // 출력된 바이트 수를 세기 위한 변수

            // 파일의 내용을 바이트 단위로 읽고, 각 바이트를 16진수 형식으로 출력
            while ((data = input.read()) != -1) {
                output.printf("%02X ", data); // 바이트를 16진수 두 자리로 출력
                if (++i % 16 == 0) { // 16바이트마다 줄바꿈
                    output.println();
                }
            }

            // 마지막 줄바꿈 추가 - 16바이트가 되지 않는 경우
            if (i % 16 != 0) {
                output.println();
            }

        } catch (IOException e) { // 파일 읽기 중 예외 처리
            e.printStackTrace();
        }
    }
}
 
java HexaViewer HexaViewer.class                                    
CA FE BA BE 00 00 00 37 00 5A 0A 00 0A 00 32 09 
00 33 00 34 08 00 35 0A 00 2E 00 36 0A 00 33 00 
37 07 00 38 0A 00 06 00 39 0A 00 06 00 3A 08 00 
3B 07 00 3C 0A 00 3D 00 3E 0A 00 2E 00 3F 0A 00 
2E 00 40 0A 00 2E 00 41 07 00 42 0A 00 0F 00 43 
0A 00 06 00 41 07 00 44 0A 00 12 00 45 07 00 46 
01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 
00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D
62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C
56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00 04
74 68 69 73 01 00 0C 4C 48 65 78 61 56 69 65 77
65 72 3B 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C
6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67
3B 29 56 01 00 04 64 61 74 61 01 00 01 49 01 00
01 69 01 00 06 6F 75 74 70 75 74 01 00 15 4C 6A 
61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65
61 6D 3B 01 00 05 69 6E 70 75 74 01 00 19 4C 6A
61 76 61 2F 69 6F 2F 46 69 6C 65 49 6E 70 75 74
53 74 72 65 61 6D 3B 01 00 01 65 01 00 15 4C 6A
61 76 61 2F 69 6F 2F 49 4F 45 78 63 65 70 74 69
6F 6E 3B 01 00 04 61 72 67 73 01 00 13 5B 4C 6A
61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
01 00 09 69 6E 70 75 74 46 69 6C 65 01 00 12 4C
6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67
3B 01 00 0D 53 74 61 63 6B 4D 61 70 54 61 62 6C
65 07 00 28 07 00 47 07 00 48 01 00 0A 45 78 63
65 70 74 69 6F 6E 73 01 00 0A 53 6F 75 72 63 65
46 69 6C 65 01 00 0F 48 65 78 61 56 69 65 77 65
72 2E 6A 61 76 61 0C 00 15 00 16 07 00 49 0C 00
4A 00 22 01 00 1F 55 53 41 47 45 3A 20 6A 61 76
61 20 48 65 78 61 56 69 65 77 65 72 20 46 49 4C
45 4E 41 4D 45 0C 00 4B 00 4C 0C 00 4D 00 4E 01 
00 17 6A 61 76 61 2F 69 6F 2F 46 69 6C 65 49 6E
70 75 74 53 74 72 65 61 6D 0C 00 15 00 4C 0C 00
4F 00 50 01 00 05 25 30 32 58 20 01 00 10 6A 61
76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 07 00
51 0C 00 52 00 53 0C 00 54 00 55 0C 00 4B 00 16
0C 00 56 00 16 01 00 13 6A 61 76 61 2F 6C 61 6E
67 2F 54 68 72 6F 77 61 62 6C 65 0C 00 57 00 58
01 00 13 6A 61 76 61 2F 69 6F 2F 49 4F 45 78 63
65 70 74 69 6F 6E 0C 00 59 00 16 01 00 0A 48 65
78 61 56 69 65 77 65 72 01 00 10 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 01 00 13 6A 61
76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61
6D 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79
73 74 65 6D 01 00 03 6F 75 74 01 00 07 70 72 69
6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61
6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 65
78 69 74 01 00 04 28 49 29 56 01 00 04 72 65 61
64 01 00 03 28 29 49 01 00 11 6A 61 76 61 2F 6C
61 6E 67 2F 49 6E 74 65 67 65 72 01 00 07 76 61
6C 75 65 4F 66 01 00 16 28 49 29 4C 6A 61 76 61
2F 6C 61 6E 67 2F 49 6E 74 65 67 65 72 3B 01 00 
06 70 72 69 6E 74 66 01 00 3C 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 5B 4C 6A
61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B
29 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53
74 72 65 61 6D 3B 01 00 05 63 6C 6F 73 65 01 00
0D 61 64 64 53 75 70 70 72 65 73 73 65 64 01 00
18 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 54 68 72
6F 77 61 62 6C 65 3B 29 56 01 00 0F 70 72 69 6E
74 53 74 61 63 6B 54 72 61 63 65 00 21 00 14 00
0A 00 00 00 00 00 02 00 01 00 15 00 16 00 01 00
17 00 00 00 2F 00 01 00 01 00 00 00 05 2A B7 00
01 B1 00 00 00 02 00 18 00 00 00 06 00 01 00 00
00 05 00 19 00 00 00 0C 00 01 00 00 00 05 00 1A
00 1B 00 00 00 09 00 1C 00 1D 00 02 00 17 00 00
02 00 00 06 00 06 00 00 00 A8 2A BE 04 9F 00 0F
B2 00 02 12 03 B6 00 04 03 B8 00 05 2A 03 32 4C
BB 00 06 59 2B B7 00 07 4D B2 00 02 4E 03 36 05
2C B6 00 08 59 36 04 02 9F 00 28 2D 12 09 04 BD
00 0A 59 03 15 04 B8 00 0B 53 B6 00 0C 57 84 05
01 15 05 10 10 70 9A FF DA 2D B6 00 0D A7 FF D3
15 05 10 10 70 99 00 07 2D B6 00 0D 2D C6 00 23
2D B6 00 0E A7 00 1C 3A 04 2D C6 00 13 2D B6 00
0E A7 00 0C 3A 05 19 04 19 05 B6 00 10 19 04 BF
2C B6 00 11 A7 00 15 4E 2C B6 00 11 A7 00 0B 3A
04 2D 19 04 B6 00 10 2D BF A7 00 08 4D 2C B6 00
13 B1 00 05 00 23 00 62 00 6D 00 0F 00 73 00 77 
00 7A 00 0F 00 1F 00 86 00 8D 00 0F 00 8E 00 92
00 95 00 0F 00 16 00 9F 00 A2 00 12 00 03 00 18
00 00 00 56 00 15 00 00 00 07 00 06 00 08 00 0E
00 09 00 12 00 0C 00 16 00 0E 00 1F 00 0F 00 23
00 12 00 26 00 14 00 31 00 15 00 44 00 16 00 4F
00 17 00 56 00 1B 00 5E 00 1C 00 62 00 1F 00 6D
00 0E 00 86 00 1F 00 8D 00 0E 00 9F 00 21 00 A2
00 1F 00 A3 00 20 00 A7 00 22 00 19 00 00 00 48
00 07 00 2D 00 35 00 1E 00 1F 00 04 00 26 00 3C
00 20 00 1F 00 05 00 23 00 63 00 21 00 22 00 03
00 1F 00 80 00 23 00 24 00 02 00 A3 00 04 00 25
00 26 00 02 00 00 00 A8 00 27 00 28 00 00 00 16
00 92 00 29 00 2A 00 01 00 2B 00 00 00 74 00 0E
12 FF 00 13 00 06 07 00 2C 07 00 2D 07 00 06 07
00 2E 00 01 00 00 FF 00 2F 00 06 07 00 2C 07 00
2D 07 00 06 07 00 2E 01 01 00 00 F9 00 0B 4A 07
00 0F FF 00 0C 00 05 07 00 2C 07 00 2D 07 00 06
07 00 2E 07 00 0F 00 01 07 00 0F 08 F9 00 02 46
07 00 0F FF 00 07 00 04 07 00 2C 07 00 2D 07 00
06 07 00 0F 00 01 07 00 0F 07 F9 00 01 42 07 00
12 04 00 2F 00 00 00 04 00 01 00 12 00 01 00 30
00 00 00 02 00 31
 

[15-3] 다음은 디렉토리의 요약정보를 보여주는 프로그램이다. 파일의 개수, 디렉토리의 개수, 파일의 총 크기를 계산하는 countFiles( )를 완성하시오.

 

C:\jdk1.8\work\ch15>java DirectoryInfoTest .

총 786개의 파일

총 27개의 디렉토리

크기 2566228 bytes

 

import java.io.File;

class DirectoryInfoTest {

    static int totalFiles = 0;
    static int totalDirs = 0;
    static long totalSize = 0; // 파일 크기는 long으로 해야 모든 파일의 크기를 다룰 수 있습니다

    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("USAGE: java DirectoryInfoTest DIRECTORY");
            System.exit(0);
        }

        File dir = new File(args[0]);

        if (!dir.exists() || !dir.isDirectory()) {
            System.out.println("유효하지 않은 디렉토리입니다.");
            System.exit(0);
        }

        countFiles(dir);

        System.out.println();
        System.out.println("총 " + totalFiles + "개의 파일");
        System.out.println("총 " + totalDirs + "개의 디렉토리");
        System.out.println("크기 " + totalSize + " bytes");
    }

    public static void countFiles(File dir) {
        File[] files = dir.listFiles(); // 1. dir의 파일목록(File[])을 얻어온다.

        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) { // 2. 디렉토리이면
                    totalDirs++;
                    countFiles(file); // countFiles()를 재귀호출한다.
                } else { // 3. 파일이면
                    totalFiles++;
                    totalSize += file.length(); // 파일의 크기를 totalSize에 더한다.
                }
            }
        }
    }
}
 

[15-4] 커맨드라인으로부터 여러 파일의 이름을 입력받고, 이 파일들을 순서대로 합쳐서 새로운 파일을 만들어내는 프로그램(FileMergeTest.java)을 작성하시오. 단, 합칠 파일의 개수에는 제한을 두지 않는다.

 

C:\jdk1.8\work\ch15>java FileMergeTest

USAGE: java FileMergeTest MERGE_FILENAME FILENAME1 FILENAME2 ...

 

C:\jdk1.8\work\ch15>java FileMergeTest result.txt 1.txt 2.txt 3.txt

 

C:\jdk1.8\work\ch15>type result.txt

1111111111

2222222222

33333333333333

 

C:\jdk1.8\work\ch15>java FileMergeTest result.txt 1.txt 2.txt

 

C:\jdk1.8\work\ch15>type result.txt

1111111111

2222222222

 

C:\jdk1.8\work\ch15>type 1.txt

1111111111

 

C:\jdk1.8\work\ch15>type 2.txt

2222222222

 

C:\jdk1.8\work\ch15>type 3.txt

33333333333333

 

C:\jdk1.8\work\ch15>

 

import java.io.*;
import java.util.*;

public class FileMergeTest {
    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("USAGE: java FileMergeTest MERGE_FILENAME FILENAME1 FILENAME2 ... ");
            System.exit(0);
        }

        try {
            Vector<FileInputStream> v = new Vector<>();

            for (int i = 1; i < args.length; i++) {
                File f = new File(args[i]);

                if (f.exists()) {
                    v.add(new FileInputStream(args[i]));
                } else {
                    System.out.println(args[i] + " - 존재하지 않는 파일입니다.");
                    System.exit(0);
                }
            }

            SequenceInputStream input = new SequenceInputStream(v.elements());
            FileOutputStream output = new FileOutputStream(args[0]);

            int data;
            while ((data = input.read()) != -1) {
                output.write(data);
            }

            input.close();
            output.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 

풀이

1. 커맨드라인 인자 확인
args.length가 2보다 작으면 사용법을 출력하고 프로그램 종료.

2. 파일 입력 스트림 생성
Vector를 사용해 여러 FileInputStream을 저장.
입력 파일이 존재하지 않으면 오류 메시지 출력하고 프로그램 종료.

3. 파일 병합
SequenceInputStream을 사용해 벡터의 요소들을 병합.
FileOutputStream을 사용해 병합된 데이터를 출력 파일에 저장.
 

참고

SequenceInputStream

  • 여러 입력 스트림을 하나로 연결 -> 여러 개 파일을 하나로 읽을 수 있음
  • 간편한 구현 -> 반복문이나 추가적인 조건문이 필요하지 않음
  • 효율성 -> 데이터 병합 효율이 좋음

[15-5] 다음은 FilterWriter를 상속받아서 직접 구현한 HtmlTagFilterWriter를 사용해서 주어진 파일에 있는 태그를 모두 제거하는 프로그램이다. HtmlTagFilterWriter의 write( )가 태그를 제거하도록 코드를 완성하시오.

 

C:\jdk1.8\work\ch15>java Exercise15_5 test.html result.txt

C:\jdk1.8\work\ch15>type result.txt

 

New Document

 

> 안녕하세요 태그 없애기 테스트용 파일입니다.

< 태그가 열린 채로 끝난 것은 태그로 처리하지 마세요.

 

C:\jdk1.8\work\ch15>type test.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE> New Document </TITLE>

</HEAD>

<BODY>

> 안녕하세요 태그 없애기 테스트용 파일입니다.

</BODY>

< 태그가 열린 채로 끝난 것은 태그로 처리하지 마세요.

 

import java.io.*;

class Exercise15_5 {
    public static void main(String[] args) {
        if(args.length!=2){
            System.out.println("USAGE: java Exercise15_5 TAGET_FILE RESULT_FILE");
            System.exit(0);
        }

        String inputFile =args[0];
        String outputFile=args[1];

        try {
            BufferedReader input = new BufferedReader(new FileReader(inputFile));
            HtmlTagFilterWriter output = new HtmlTagFilterWriter(new FileWriter(outputFile));

            int ch = 0;

            while ((ch = input.read()) != -1) {
                output.write(ch);
            }

            input.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class HtmlTagFilterWriter extends FilterWriter {
    StringWriter tmp = new StringWriter();
    boolean inTag = false;

    HtmlTagFilterWriter(Writer out) {
        super(out);
    }

    public void write(int c) throws IOException {
        if (c == '<') {
            inTag = true;
        } else if (c == '>') {
            inTag = false;
            tmp.getBuffer().setLength(0); // Clear the StringWriter buffer
        } else if (inTag) {
            tmp.write(c);
        } else {
            out.write(c);
        }
    }

    public void close() throws IOException {
        out.write(tmp.toString()); // Write any remaining content in the StringWriter
        super.close(); // Close the underlying writer
    }
}
 

풀이

1. Exercise15_5 클래스
- main 메서드:
프로그램이 2개의 인수를 필요로 함
BufferedReader와 HtmlTagFilterWriter를 생성해 파일을 읽고 쓰는 작업 수행
입력 파일에서 한 문자씩 읽어와 HtmlTagFilterWriter로 쓰는 역할 수행
작업이 끝난 후 파일을 닫음

2. HtmlTagFilterWriter 클래스
- 필드:
StringWriter tmp: 태그 내의 문자를 임시로 저장하기 위해 사용되는 필드
boolean inTag: 현재 태그 내부에 있는지를 추적하는 필드

- 생성자:
HtmlTagFilterWriter(Writer out): FilterWriter를 초기화하는 생성자

- write 메서드:
< 문자를 만나면 inTag를 true로 설정함
> 문자를 만나면 inTag를 false로 설정하고, StringWriter의 버퍼를 비움
태그 내부에 있는 동안에는 StringWriter에 문자를 쓰는 역할 수행
태그 외부에 있는 동안에는 실제 출력 스트림에 문자를 씀

- close 메서드:
남아있는 내용을 출력하고 스트림을 닫는 역할 수행
기반 스트림을 닫는 작업 수행
 

[15-6] 다음은 콘솔 명령어 중에서 디렉토리를 변경하는 cd명령을 구현한 것이다. 알맞은 코드를 넣어 cd( )를 완성하시오.

 

C:\jdk1.8\work\ch15>java Exercise15_6

C:\jdk1.8\work\ch15>>

C:\jdk1.8\work\ch15>>cd ch15

유효하지 않은 디렉토리입니다.

C:\jdk1.8\work\ch15>>cd ..

C:\jdk1.8\work>>cd ch15

C:\jdk1.8\work\ch15>>

C:\jdk1.8\work\ch15>>cd .

C:\jdk1.8\work\ch15

C:\jdk1.8\work\ch15>>q

 

import java.io.*;
import java.util.*;
import java.util.regex.*;

class Exercise15_6 {
    static String[] argArr; // 입력한 매개변수를 담기위한 문자열배열
    static File curDir; // 현재 디렉토리

    static {
        try {
            curDir = new File(System.getProperty("user.dir"));
        } catch (Exception e) {
        }
    }

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        while (true) {
            try {
                String prompt = curDir.getCanonicalPath() + ">>";
                System.out.print(prompt);

                // 화면으로부터 라인단위로 입력받는다.
                String input = s.nextLine();

                input = input.trim(); // 입력받은 값에서 불필요한 앞뒤 공백을 제거한다.
                argArr = input.split("\\s+"); // 공백을 기준으로 매개변수를 나눈다.

                String command = argArr[0].trim();

                if ("".equals(command))
                    continue;

                command = command.toLowerCase(); // 명령어를 소문자로 바꾼다.

                if (command.equals("q")) { // q또는 Q를 입력하면 실행종료한다.
                    System.exit(0);
                } else if (command.equals("cd")) {
                    cd();
                } else {
                    for (int i = 0; i < argArr.length; i++) {
                        System.out.println(argArr[i]);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("입력오류입니다.");
            }
        } // while(true)
    } // main

    public static void cd() {
        if (argArr.length == 1) {
            System.out.println(curDir);
            return;
        } else if (argArr.length > 2) {
            System.out.println("USAGE: cd directory");
            return;
        }

        String subDir = argArr[1];

        /*
         * (1) 아래의 로직에 맞게 코드를 작성하시오 .
         * 1. 입력된 디렉토리(subDir)가  ".."이면,
         *  1.1 현재 디렉토리의 조상 디렉토리를 얻어서 현재 디렉토리로 지정한다.
         *     (File클래스의 getParentFile()을 사용) 
         * 2. 입력된 디렉토리(subDir)가 "."이면 단순히 현재 디렉토리의 경로를 화면에 출력한다.
         * 3. 1또는 2의 경우가 아니면,
         * 	3.1 입력된 디렉토리(subDir)가 현재 디렉토리의 하위디렉토리인지 확인한다. 
         *  3.2 확인결과가 true이면 현재 디렉토리(curDir)을 입력된 디렉토리(subDir)로 변경한다. 
         *  3.3 확인결과가 false이면 "유효하지 않은 디렉토리입니다."고 화면에 출력한다.
         */

        if (subDir.equals("..")) {
            curDir = curDir.getParentFile();
        } else if (subDir.equals(".")) {
            System.out.println(curDir);
        } else {
            File newDir = new File(curDir, subDir);
            if (newDir.exists() && newDir.isDirectory()) {
                curDir = newDir;
            } else {
                System.out.println("유효하지 않은 디렉토리입니다.");
            }
        }
    }
}
 

[15-7] 다음의 코드는 대화내용을 파일에 저장할 수 있는 채팅 프로그램이다. '저장' 버튼을 누르면 대화내용이 저장되도록 알맞은 코드를 넣어 완성하시오.

 

import java.io.*;
import java.awt.*;
import java.awt.event.*;

class ChatWin extends Frame {
    String nickname = "";
    TextArea ta = new TextArea();
    Panel p = new Panel();
    TextField tf = new TextField(30);
    Button bSave = new Button("저장");

    ChatWin(String nickname) {
        super("Chatting");
        this.nickname = nickname;

        setBounds(200, 100, 300, 200);

        p.setLayout(new FlowLayout());
        p.add(tf);
        p.add(bSave);

        add(ta, "Center");
        add(p, "South");

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        bSave.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                FileDialog fileSave = new FileDialog(ChatWin.this, "파일저장", FileDialog.SAVE);
                fileSave.setVisible(true);
                String fileName = fileSave.getDirectory() + fileSave.getFile();
                saveAs(fileName);
            }
        });

        EventHandler handler = new EventHandler();
        ta.addFocusListener(handler);
        tf.addFocusListener(handler);
        tf.addActionListener(handler);

        ta.setText("#" + nickname + " 님 즐거운 채팅되세요.");
        ta.setEditable(false);
        setResizable(false);
        setVisible(true);
        tf.requestFocus();
    }

    void saveAs(String fileName) {
        /*
         * (1) 알맞은 코드를 넣어 완성하시오 .
         */
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
            writer.write(ta.getText());
        } catch (IOException e) {
            System.out.println("파일 저장 중 오류가 발생했습니다: " + e.getMessage());
        }
    } // saveAs 메서드의 끝

    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("USAGE: java ChatWin NICKNAME");
            System.exit(0);
        }

        new ChatWin(args[0]);
    } // main

    class EventHandler extends FocusAdapter implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            String msg = tf.getText();
            if ("".equals(msg)) return;

            ta.append("\r\n" + nickname + ">" + msg);
            tf.setText("");
        }

        public void focusGained(FocusEvent e) {
            tf.requestFocus();
        }
    } // class EventHandler
} // class
 
 
사진 삭제
 
사진 삭제

사진 설명을 입력하세요.


[15-8] 다음의 코드는 파일로부터 한 줄 씩 데이터를 읽어서 보여주는 프로그램이다. 버튼을 이용해서 첫 줄, 다음 줄, 이전 줄, 마지막 줄로 이동할 수 있으며, 각 줄의 개행문자는 '|'를 사용한다. (1)~(2)에 알맞은 코드를 넣어 완성하시오.

 

import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;

class WordStudy extends Frame {
    Button first = new Button("<<");
    Button prev = new Button("<");
    Button next = new Button(">");
    Button last = new Button(">>");
    Panel buttons = new Panel();
    TextArea ta = new TextArea();
    ArrayList<String> wordList = new ArrayList<>();


    // final String WORD_FILE = "word_data.txt";
    // 테스트 할 때는 절대경로로 테스트함 

    final String CR_LF = System.getProperty("line.separator");

    int pos = 0;

    WordStudy(String title) {
        super(title);

        buttons.add(first);
        buttons.add(prev);
        buttons.add(next);
        buttons.add(last);
        add("South", buttons);
        add("Center", ta);

        EventHandler handler = new EventHandler();
        addWindowListener(handler);
        first.addActionListener(handler);
        prev.addActionListener(handler);
        next.addActionListener(handler);
        last.addActionListener(handler);

        loadFile(WORD_FILE);

        setBackground(Color.BLACK);
        setSize(300, 200);
        setLocation(200, 200);
        setResizable(true);
        setVisible(true);
        showFirst();
    }

    void showFirst() {
        pos = 0;
        display(pos);
    }

    void showPrevious() {
        pos = (pos > 0) ? --pos : 0;
        display(pos);
    }

    void showNext() {
        int size = wordList.size();
        pos = (pos < size - 1) ? ++pos : size - 1;
        display(pos);
    }

    void showLast() {
        pos = wordList.size() - 1;
        display(pos);
    }

    void display(int pos) { // pos 위치에 있는 라인의 내용을 보여준다.
        /*
         * (1) 아래의 로직에 맞게 코드를 작성하시오.
         * 1. wordList에서 pos번째의 위치에 있는 데이터를 읽어온다.
         * 2. StringTokenizer를 이용해서 '|'를 구분자로 자른다.
         * 3. 잘라진 Token에 개행문자(CR_LF)를 붙여서 StringBuffer에 붙인다.(append)
         * 4. StringBuffer의 내용을 뽑아서 TextArea에 보여준다.
         */
        String line = wordList.get(pos);
        StringTokenizer st = new StringTokenizer(line, "|");
        StringBuffer sb = new StringBuffer();

        while (st.hasMoreTokens()) {
            sb.append(st.nextToken()).append(CR_LF);
        }

        ta.setText(sb.toString());
    }

    void loadFile(String fileName) {
        /*
         * (2) 아래의 로직에 맞게 코드를 작성하시오.
         * 1. BufferedReader와 FileReader를 이용해서 파일의 내용을 라인 단위로 읽는다.
         * 2. 읽어온 라인을 wordList에 저장한다.
         * 3. 만일 예외가 발생하면 프로그램을 종료한다.
         */
        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
            String line;
            while ((line = br.readLine()) != null) {
                wordList.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static void main(String args[]) {
        WordStudy mainWin = new WordStudy("WordStudy");
        System.out.println("Current working directory: " + new File(".").getAbsolutePath());
    }

    class EventHandler extends WindowAdapter implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            Button b = (Button) ae.getSource();

            if (b == first) {
                showFirst();
            } else if (b == prev) {
                showPrevious();
            } else if (b == next) {
                showNext();
            } else if (b == last) {
                showLast();
            }
        }

        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }
}
 
 
사진 삭제

사진 설명을 입력하세요.


[15-9] 다음은 메모장 프로그램의 일부인데, fileOpen( )과 saveAs( )가 아직 구현되어 있지 않다. 이 두 메서드를 구현하여 프로그램을 완성하시오.

 

import java.awt.*;
import java.awt.event.*;
import java.io.*;

class Exercise15_9 extends Frame {
    String fileName;
    TextArea content;
    MenuBar mb;
    Menu mFile;
    MenuItem miNew, miOpen, miSaveAs, miExit;

    Exercise15_9(String title) {
        super(title);
        content = new TextArea();
        add(content);

        mb = new MenuBar();
        mFile = new Menu("File");
        miNew = new MenuItem("New");
        miOpen = new MenuItem("Open");
        miSaveAs = new MenuItem("Save As...");
        miExit = new MenuItem("Exit");

        mFile.add(miNew);
        mFile.add(miOpen);
        mFile.add(miSaveAs);
        mFile.addSeparator(); // 메뉴 분리선(separator)을 넣는다.
        mFile.add(miExit);

        mb.add(mFile); // MenuBar에 Menu를 추가한다.
        setMenuBar(mb); // Frame에 MenuBar를 포함시킨다.

        //메뉴에 이벤트 핸들러를 등록한다.
        MyHandler handler = new MyHandler();
        miNew.addActionListener(handler);
        miOpen.addActionListener(handler);
        miSaveAs.addActionListener(handler);
        miExit.addActionListener(handler);

        setSize(300, 200);
        setVisible(true);
    }

    //선택된 파일의 내용을 읽어서 TextArea에 보여주는 메서드
    void fileOpen(String fileName) {
        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
            StringWriter sw = new StringWriter();
            String line;
            while ((line = br.readLine()) != null) {
                sw.write(line + "\n");
            }
            content.setText(sw.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // TextArea의 내용을 지정된 파일에 저장하는 메서드
    void saveAs(String fileName) {
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))) {
            bw.write(content.getText());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        Exercise15_9 mainWin = new Exercise15_9("Text Editor");
    } // main메서드의 끝

    //메뉴를 클릭했을 때 메뉴별 처리코드
    class MyHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();

            if (command.equals("New")) {
                content.setText("");
            } else if (command.equals("Open")) {
                FileDialog fileOpen = new FileDialog(Exercise15_9.this, "파일열기");
                fileOpen.setVisible(true);
                fileName = fileOpen.getDirectory() + fileOpen.getFile();
                System.out.println(fileName);  //선택된 파일의 내용을 TextArea에 보여준다.
                fileOpen(fileName);
            } else if (command.equals("Save As...")) {
                FileDialog fileSave = new FileDialog(Exercise15_9.this, "파일저장", FileDialog.SAVE);
                fileSave.setVisible(true);
                fileName = fileSave.getDirectory() + fileSave.getFile();
                System.out.println(fileName);
                //현재 TextArea의 내용을 선택된 파일에 저장한다.
                saveAs(fileName);
            } else if (command.equals("Exit")) {
                System.exit(0); //프로그램을 종료시킨다.
            }
        }
    } // class MyHandler
} // Exercise15_9클래스의 끝
 

로직 확인 방법

 

  1. 파일 실행 및 메모작성
  2. file > save as > 경로 설정 > 저장
  3. exit으로 프로그램 종료
  4. 해당 경로에 저장된 메모 조회
 
 
반응형