티스토리 뷰

이 데이터를 가진 txt파일이 아래와 같이 원하는 형식으로 출력되게 할 것이다. 

 

★ Maven project를 이용하여 project 파일 만들기

 

☆ Maven이란?

- 필요한 라이브러리를 특정 문서(pom.xml)에 정의해 놓으면 네트워크를 통해서 라이브러리들을 자동으로 다운 받아준다.

- 기본적인 프로젝트 구조를 만들어준다.

 

- 장점

  ① 라이브러리의 관리 용이에 도움

  ② 프로젝트의 작성부터 컴파일,테스트 등 프로젝트 라이프 사이클에 포함되는 각 테스트 지원

 

출처 : https://mangkyu.tistory.com/8

  

- New -> others -> marven 검색 -> marven project 생성

 

-  src/main/java : code 저장

-  src/main/resorces : static files 저장

 

우선 , 할 일을 적어놓은 todo-data-simple.text 파일을 src/main/resorces에 저장한다. 


★ 해당 파일이 위치한 경로와 데이터 수 조회하기.

 App.java 파일을 rc/main/java에 생성한 App.java파일을 보자.

 

1 -1. String 타입의 RESOURCES 변수를 만든다. 

   

1 -2. 

☆ final

- final의 사전적인 의미는 마지막의, 최종적인 이라는 뜻을 가지고 있다. 

  final로 선언된 변수가 할당되면 항상 같은 값을 가진다.  즉, 불변이라고 생각하면 될 것 같다.

 상수나 메서드,클래스를 정의한 뒤 변경하지 못하게 할 때 변경한다.

 

그럼, Static final은 무엇일까? static은 클래스 변수이다. 그러므로 static final은 객체 (인스턴스)가 아닌 클래스에 존재하는 단 하나의 상수이다.즉, 객체마다 값이 바뀌는 것이 아닌 클래스에 존재하는 상수이므로 선언과 동시에 초기화 해줘야하는 클래스 상수이다.

 

따라서, 이 라인의 해석은 " 자, 이제 resources에 있는 파일은 string 타입의 RESOURCES 이름을 가진 변수입니다. 건드려도 끄덕없어요. 변하지 않습니다. " 라고 선언을 해주는 것이다. 

 

 

2. App.java에서 todo-data-simple.txt 파일을 읽기 위해서는 해당 파일이 위치한 경로를 알아보자.

 

   final은 위에서 말했듯이 불변의 값을 설정하는 것이다. 

   Path는 하나의 타입이다. 왜냐하면  filePath 변수명 앞에 입력되었기 때문이다.

   paths.get은 값이고, filePath에 대입이 된다.

   내가 이때 까지 입력했던 타입의 종류를 살펴보았다.

   또한, Path를 import 해줘야한다.  dev.todo.mvc의 패키지와 같은 위계이다. 

   단축키는 ctrl+shift+o 이다. 

   import 작업을 해주면 다른 패키지 안의 클래스를 사용하기 위해서

   매번 클래스 이름 앞에 패키지를 붙여하는 번거로움을 줄 일 수 있다. 

   즉, 다른 패키지 안의 클래스를 사용할 때 클래스 이름만 적어주면 된다.

 

 

   3. 읽어들인 파일 todo-data-simple.text의 데이터 수를 조회해보자

 

       우리가 활용할 todo-data-simple.text가 몇 줄인지 파악해보겠다.

       길이를 나타는 Long 타입의 numberOfLines의 변수를 만든다.

     

       근데 IOexception의 에러가 나타난다. (IO 는 Input,Out의 약자)

      코드를 작성했을 때, 문법적으로 문제는 없지만

      "내가 지정한 경로가 틀렸을 경우에 어떻게 할 거야? 그 예외를 처리해 줘"라고 말하는 에러이다. 

       즉, 데이터 입출력 기능을 수행할 때

       적절한 예외발생으로 동작을 STOP해주어 불필요한 서비스 이용을 막아주는것을 말한다.

       해결 방법으로는,  throws Excetion을 클래스 명 있는 곳에 입력해주면 된다. 

       

      콘솔에 출력하면 결과적으로,

       해당 파일이 위치한 경로todo-data-simple.text 데이터 수가 3인 것을 확인할 수 있다. 

 

    콘솔 창 


 

★ 파일을 읽어들이기

이제 이 데이터를 배열로 만들어 사용하자.

 

1. Long 타입 -> int 타입으로 변환

    Long타입은 너무 크기때문에 intValue라는 메서드를 이용하여 변환하여 읽어들인다. 

 

파일을 보고 데이터를 각 항목별로 구별해보았다.

 

 

2. 할 일 번호들을 저장할 Long 타입의 배열, todoNumbers를 만든다.

 

3. 할 일 명칭들을 저장할 String타입의 배열, todoTitle을 만든다.

 

4. 할 일 내용들을 저장할 String 타입의 배열, todoDescriptions를 만든다.

 

5. 할 일 날짜들을 저장할 LocalDate 타입의 배열, todoDueDate를 만든다. 

 

(배열 안에 파일을 읽어들일 때마다 데이터의 수가 다르므로 3이 아닌 rows를 입력해준다.)

 

6. 파일을 읽어들인다.

    java.util의 List를  import 해야 한다. 

 

lines를 출력해보았다. 양 끝에 대괄호가 있고,  콤마(,)로 구분되어있다. 어쨌든 파일을 읽어들인 것에 성공했다.


네모칸이 하나의 문자열이라고 보면 된다. 

이 txt 파일은 TSV로 구분되어있는 파일이다.

TSV는 Tab Separated Value의 약자로 빈 공간 (Tab)으로 구분되어 있는 것을 뜻한다.

참고로 CSV는 Comma Separtated Value의 약자로 콤마 (,) 로 구분되어있는 것을 뜻한다.

 

Columns로 공백으로 구분되어있는 각 항목들을 구별해주는 것이다.

1. index 값을 0으로 초기화 한다.

 

2. for each를 작성한다. 

    문자열 clolums를 만들어 line을 탭으로 구분하겠다는 뜻이다.  escape tab이라 읽고,  줄바꿈한다고 알면 된다.

    

    그리고 columns [0] 과 columns[1]을 을 공백과 함께 출력하면  할 일 번호와 할 일 명칭이 출력된다.

 

출력 화면

    즉,  columns [0] 은 할 일 번호, columns[1]은 할 일 명칭 등이 된 것을 알 수 있다. 


★ 위에서 생성한 배열에 각각 읽어들인 데이터들을 저장

columns 라고 하는 배열에 첫번째 줄의 데이터, 두번째 , 세번째 줄이 차례대로 할당된다.

새로운 줄이 할당될 때마다 그 전의 줄에 있는 데이터들은 삭제된다. 

이를 막기 위해, 그전의 데이터들이 저장될 수 있도록 따로 변수를 만들어줘야한다. 

 

 

 

5. 먼저 index 번호가 증가될 수 있게 한다. index가 순서대로 적용되어야 하기 때문이다.

 

1. 할 일 번호를 저장할 Long타입의 변수 id를 만든다.

   문자열을 숫자로 변환하는 parseLong 메서드를 이용해 columns [0] 번을 id라는 변수에 저장했다. 

   그 다음 할 일 todoNumbers 배열의 인덱스에 순서대로 저장해야한다. 

   todonumbers[index]라고 입력한 이유는 2,3번째 줄도 입력되어야하므로 index를 넣어준다. 

 

   나머지 아래 과정들도 1번과 같다. 

 

2. 할 일 제목을 저장할 변수 title을 만든다. 

   할 일 제목 배열의 인덱스에 순서대로 저장한다. 

 

3. 할 일 날짜를 저장할 변수 dueDate를 만든다.

   날짜를 입력하는 형식은  yyyy.mm.dd / yyyy/mm/dd 등등으로 다양하기 때문에 형식을 지정해줘야한다. 

   

 따라서, 상단에 DateTimeFormatter 타입의 DATE_PATTERN 변수를 지정해준다.

 물론, 우리가 가진 txt파일에 쓰여있는 날짜 형식 yyyy-MM-dd로 입력해야한다.

 대문자로 입력한 이유는 변하지 않는 상수이기 때문이다. 

 

 할 일 날짜 배열의 인덱스에 순서대로 저장해준다. 

   

4. 할 일 내용을 저장할 변수 description을 만든다.

   할 일 내용의 배열의 인덱스에 순서대로 저장한다. 

 

 


★ 원하는 형식으로 전체 Todos 조회 

 

- 원하는 형식은    00번째로 해야할 일은 : 00이고, 할 일 내용은 00입니다. 기한은 00까지 입니다로 출력할 것이다. 

 

이렇게 반복문을 이용하여 출력하면 된다. 

출력화면 

 


★ 정리하기

1. 파일 입출력을 적용하여 Todo 데이터를 읽어들인다.

 

2. 읽어들인 데이터를 Java에서 조회한다.

 

3. Primitive data(기본 타입)을 그대로 관리한다  -> 기본 타입으로 배열 생성하였다. ( int, LocalDate, String을 이용)

 

4. 배열을 활용하여 관리한다.

 

한계점

 

- 객체가 아닌 기본 자료형을 그대로 활용 중이라 관리가 불편함. 


package com.todo;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

public class App {
	
	private static final String RESOURCES = "src/main/resources/";
	private static final DateTimeFormatter DATE_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd");

	public static void main(String[] args) throws Exception {
		// App.java에서 todo-data-simple.txt파일을 읽기 위해서는
		// 해당 파일이 위치한 경로를 알아야함.
		
		// package import 단축키 : Ctrl + Shift + O
		final Path filePath = Paths.get(RESOURCES + "todo-data-simple.txt");
//		System.out.println(filePath);
		
		// 읽어들인 파일 todo-data-simple.txt의 데이터 수 조회
		Long numberOfLines = Files.lines(filePath).count();
//		System.out.println(numberOfLines);
		
		// Long 타입을 int 타입으로 변환
		int rows = numberOfLines.intValue();
		
		// 할 일 번호들을 저장할 Long 타입의 배열, todoNumbers
		Long[] todoNumbers = new Long[rows];
		
		// 할 일 제목들을 저장할 String 타입의 배열, todoTitles
		String[] todoTitles = new String[rows];
		
		// 할 일 내용들을 저장할 String 타입의 배열, todoDescriptions
		String[] todoDescriptions = new String[rows];
		
		// 할 일 날짜들을 저장할 LocalDate 타입의 배열, todoDueDate
		LocalDate[] todoDueDate = new LocalDate[rows];
		
		// 파일 읽기 (java.util.List import)
		List<String> lines = Files.readAllLines(filePath);
		System.out.println(lines);
		
		int index = 0;
		for (String line : lines) {
			final String[] columns = line.split("\t");
//			System.out.println(columns[0] + " " + columns[1]);
			// 위에서 생성한 배열에 각각 읽어들인 데이터들을 저장
			
			// 할 일 번호를 저장할 변수 id 
			final Long id = Long.parseLong(columns[0]);		
			// 할 일 번호 배열의 인덱스에 순서대로 저장
			todoNumbers[index] = id;
			
			// 할 일 제목을 저장할 변수 title
			final String title = columns[1];		
			// 할 일 제목 배열의 인덱스에 순서대로 저장
			todoTitles[index] = title;
			
			// 할 일 날짜를 저장할 변수 dueDate
			final LocalDate dueDate = LocalDate.parse(columns[2], DATE_PATTERN);			
			// 할 일 날짜 배열의 인덱스에 순서대로 저장
			todoDueDate[index] = dueDate;

			// 할 일 내용을 저장할 변수 description
			final String description = columns[3];			
			// 할 일 내용의 배열의 인덱스에 순서대로 저장
			todoDescriptions[index] = description;
			
			// 인덱스값 1씩 증가
			index++;
		} // forEach() 끝
		
		// 전체 Todos 조회 (일반적인 반복문 활용)
		// 00번 째로 해야 할 일은 : 00이고, 할 일 내용은 00 입니다. 기한은 00 까지입니다.
		for (int i = 0; i < todoNumbers.length; i++) {
			System.out.print(todoNumbers[i] + "번 째로 해야할 일은 : ");
			System.out.print(todoTitles[i] + "이고, 할 일 내용은 ");
			System.out.print(todoDescriptions[i] + " 입니다. 기한은 ");
			System.out.print(todoDueDate[i] + " 까지 입니다.\n");
		}
		
	} // main() 끝

} // App.java 끝

 

강의를 들을 때는 내가 뭘 하고 있는지,  잘 하고 있는 건지 경황이 없다. 

일단 강의를 따라가려고 분주히 뭘 입력하고 있는 내 자신을 발견하고 있다.

 

하지만 여기에 기록하면서 강의를 들을 때보다는 이해가 훨씬 더 잘된다.

그래서 기록, 복습의 중요성을 점점 크게 깨닫고 있다. 

 

이것들이 모여모여 나에게  밑거름이 되어 크고 건강한 나무가 되었으면 좋겠다.