IO 를 이용한 파일 검색기

0verfl0w767·2023년 5월 17일
0

과제 문제

검색할 키워드를 입력한 뒤 txt 파일의 경로를 입력하여 해당 파일 안에 주어진 키워드가 있는지 검사하는 Java 프로그램을 작성하시오.

객체지향 프로그래밍 수업에서 배운 파일 입출력 처리 단원에 대한 응용 문제이다.

코드를 궁금해하는 사람들이 많아서 글로 작성한다. 공부에 도움이 되길 바람.

참고로 교수님이 과제 코드를 실제로 보시기 때문에 그대로 복붙해서 내지는 말 것.

문제 의도

BufferedReader에 있는 readLine()를 사용하지 않고서
직접 FileReader/FileInputStream에 있는 read()를 사용하여 구현하는 것

대부분 구글링을 통해서 BufferedReader을 사용했을 것이다. 소켓 프로그래밍에서

BufferedReader을 사용했기 때문에 이 과제에서 사용해도 전혀 문제가 없다.

구현에 대한 정답은 없기에 내 코드도 정석이 아닌 것을 생각할 것.

문제 해설


  • FileReader -> FileInputStream ( FileInputStream.getChannel().size() 사용 )
  • InputStreamReader ( new InputStreamReader(file, "UTF-8") 사용 )

file = new FileInputStream(filePath);
int fileSize = (int) file.getChannel().size();
fileRead = new char[fileSize];

FileReader이 아닌 FileInputStream을 사용한 이유는 파일의 정확한 사이즈 값을 얻어오기 위해

사용했다. (그렇지 않으면 new char[1024] 와 같이 직접 사이즈를 정해야되기 때문이다.)

1024 그 이상의 파일의 사이즈를 읽게 되면 오류를 뱉고 사망하기 때문에 조심할 것.

utf8 = new InputStreamReader(file, "UTF-8");

InputStreamReader을 사용한 이유는 UTF-8 인코딩을 통해 한글 깨짐을 방지하기 위해

사용되었다. 이것은 수업시간에 배운 내용이 아니므로 구글링으로 찾을 수 있다.

while ((char_ = utf8.read()) != -1) {
	if (char_ == 10) {
		fileReadLineSize++;
	}
	fileRead[count++] = (char) char_;
}

먼저 첫번째 while문을 통해 10(ASCII CODE (LF))로 텍스트 줄의 갯수를 파악한다.

텍스트 줄의 갯수를 int fileReadLineSize 변수에 저장하고 char[] fileRead 변수에 각 문자들을 저장한다.

while (true) {
	if (fileReadCount > count) {
		break;
	}
	if (fileReadLine[fileReadLineCount] == null) { // 초기화 안할 경우 null이 앞에 붙는 오류
		fileReadLine[fileReadLineCount] = "";
	}
	if (fileRead[fileReadCount] == 10) { // 10 : LF
		fileReadLineCount++;
	} else {
		fileReadLine[fileReadLineCount] += fileRead[fileReadCount];
	}
	fileReadCount++;
}

다음 while문을 통해 String Array를 이용하여 각 인덱스마다 텍스트 각 줄의 내용을 저장한다.

각 줄의 내용을 저장할때 주의할 점은 String 초기값이 설정하지 않으면 문자열을 추가할 때

null이 앞에 붙기 때문에 if문에 String[] fileReadLine의 각 배열마다 초기화를 설정하였다.

for (int i = 0; i < fileReadLine.length; i++) {
	if (fileReadLine[i].contains(keyword)) {
		System.out.println((i + 1) + "번째 줄에서 \"" + keyword + "\" 이라는 키워드가 감지되었습니다.");
		System.out.println((i + 1) + "번째 줄 -> " + fileReadLine[i]);
		findStatus = true;
	}
}
if (!findStatus) System.out.println("파일에서 " + keyword + " 이라는 키워드가 감지되지 않았습니다.");

마지막으로 contains를 사용하여 FileReadLine에 문자열이 포함되있다면 출력하면 된다.

검사후에 감지한게 없다면 없다고 출력까지 하면 코드는 끝난다.

문제 전체 코드

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

public class FindSomething {
	private static String keyword;
	private static String filePath;
	
	private static String[] fileReadLine;
	private static char[] fileRead;
	
	private static boolean findStatus = false;

	public static void main(String[] args) throws IOException {
		Scanner scan = new Scanner(System.in);
		System.out.print("파일에서 찾을 키워드를 입력하세요: ");
		keyword = scan.next();
		System.out.print("키워드를 찾을 파일 경로를 입력하세요: ");
		filePath = scan.next();
		scan.close();
		FileInputStream file = null;
		InputStreamReader utf8 = null;
		try {
			file = new FileInputStream(filePath);
			utf8 = new InputStreamReader(file, "UTF-8"); // utf-8로 안할 경우 한글 깨짐 오류
			int char_;
			int count = 0;
			int fileReadLineSize = 0;
			int fileSize = (int) file.getChannel().size();
			fileRead = new char[fileSize];
			while ((char_ = utf8.read()) != -1) {
				if (char_ == 10) {
					fileReadLineSize++;
				}
				fileRead[count++] = (char) char_;
			}
			int fileReadLineCount = 0;
			int fileReadCount = 0;
			fileReadLine = new String[fileReadLineSize + 1];
			while (true) {
				if (fileReadCount > count) {
					break;
				}
				if (fileReadLine[fileReadLineCount] == null) { // 초기화 안할 경우 null이 앞에 붙는 오류
					fileReadLine[fileReadLineCount] = "";
				}
				if (fileRead[fileReadCount] == 10) { // 10 : LF
					fileReadLineCount++;
				} else {
					fileReadLine[fileReadLineCount] += fileRead[fileReadCount];
				}
				fileReadCount++;
			}
		} catch (FileNotFoundException e){
			e.getStackTrace();
		} catch (IOException e){
			e.getStackTrace();
		} finally {
			if (file != null) file.close();
			if (utf8 != null) utf8.close();
		}
		for (int i = 0; i < fileReadLine.length; i++) {
			if (fileReadLine[i].contains(keyword)) {
				System.out.println((i + 1) + "번째 줄에서 \"" + keyword + "\" 이라는 키워드가 감지되었습니다.");
				System.out.println((i + 1) + "번째 줄 -> " + fileReadLine[i]);
				findStatus = true;
			}
		}
		if (!findStatus) System.out.println("파일에서 " + keyword + " 이라는 키워드가 감지되지 않았습니다.");
	}

}
profile
https://github.com/0verfl0w767

0개의 댓글