안녕하세요! 이번 포스팅은 Java 튜토리얼 6번째입니다.

날씨가 겨울임을 확실히 말해주고 있습니다. 역병이 계속 퍼지고 있는 가운데 감기 조심하시고 늘 건강하게 공부하시길 바랍니다!

이번 포스팅에서는 오버로드, 예외처리, 파일 입출력에 대해 다뤄 볼 것입니다.

그럼 이전시간에 정리했던 함수에 대해서 다시 한 번 상기시켜보도록 하겠습니다.

이전 포스팅 복습


함수는 입력 받는 값에 대해 어떤 연산을 처리해주는 역할을 합니다. 처리결과는 반환해주기도 하고 그렇지 않기도 합니다.

예를 들어 함수 y = 2x + 1이라고 했을 때, x를 받아서 y를 리턴해주는 함수를 어떻게 작성했나요?

public static int func (int x) {
	int y = 2x + 1;
	return y;
}

이렇게 작성하고 메인 함수에서 func(2)와 같은 방법으로 호출하여 함수의 파라미터로 2를 넘겨주어 5라는 결과값을 반환해주었습니다.

이렇게 어떤 값을 넣어줬을 때 반환해주는 값이 있는 형태가 함수의 기본 형태이지만, 반환해 주는 값이 없이 단순히 내부적인 연산만 처리하는 함수가 있습니다.

예를 들어서

public static void noReturn () {
	System.out.println("함수가 호출됨");
}

이렇게 void 형으로 선언해준 함수는 결과값을 리턴할 필요가 없이 내부적인 연산만 처리해줍니다. 대표적으로 우리가 자바 프로젝트를 생성하면 클래스 파일이 만들어지는데, 이 클래스 파일의 어떤 함수영역에 우리가 코드를 작성하고 있습니다.

public class Main {
	public static void main (String[], args) {
	// 우리는 여기에 코드를 작성합니다!
    }
}

이와 유사하게 메서드라는 개념이 있었는데 함수가 독립성이 강하다면 메서드는 클래스 의존적이라고 말할 수 있습니다.
예를 들어 문자를 정수형으로 반환해주는 메서드를 생각해봅시다.

char c = 'A';
int i = Integer.parseInt(c);

이렇게 parseInt()라는 메서드는 단독적으로 사용되기보다 Integer라는 클래스 뒤에 붙어 사용되었습니다. 이처럼 메서드는 함수보다 독립적이지 못합니다.

여기까지 이전 포스팅의 개괄적인 내용에 대해 복습해보았습니다.


오버로드

오버로드란?

오버로드는 함수명은 같으나 매개변수(parameter)의 자료형이나 개수가 다른 것을 말합니다. 예를 들어 method라는 함수가 있다고 가정해봅시다.

// 이 형태를 기본으로 가져가겠습니다.
public static void method() {
  System.out.print("method()");
}

public static void method(char c) {
  System.out.print("method(char c)");
}

public static void method(int i) {
  System.out.print("method(int i)");
}

public static void method(char c, int i) {
  System.out.print("method(char c, int i)");
}

public static void method(int i, char c) {
  System.out.print("method(int i, char c)");
}

이렇게 같은 이름의 함수인데 매개변수의 개수를 늘려주거나 위치만 바꿔주어도 자바는 이들을 서로 다른 함수로 인식합니다.

그렇지만 주의할 사항으로는

public static void method(char c, int i) {
  System.out.print("method(char c, int i)");
}
public static void method(char ch, int num) {
  System.out.print("method(char ch, int i)");
}

이렇게 parameter의 변수명만 바꿔주었다고 해서는 다른 함수로 인식하지 않습니다.

또한 return을 부여해줘도 마찬가지 입니다.

가변 인수란?

예를 들어서 다음과 같은 함수가 있다고 가정해봅시다.

public static int sumProc (int ... num) {
  int sum = 0;
  
  for (int i = 0; i < num.length; i++) {
    sum += num[i];
  }
  
  return sum;
}

함수의 parameter자리에 보시면 ...이 들어간 것을 볼 수 있습니다. 이 때는 paremeter를 배열처럼 받아줍니다. 예를 들어서 sumProc(1, 2, 3)이라고 하면 6이라는 결과가 나올 것입니다.

가변인수를 사용할 때 규칙은 함수에 다양한 parameter가 들어갈 때 가변인수는 parameter의 맨 마지막 자리에 들어가야 한다는 것입니다.


예외처리


예외란?

어떤 언어로 프로그래밍을 하든 우리는 수많은 에러를 봅니다. 그 때마다 샷건을 탕탕 치고는 하지만 어떤 부분에서 기능적인 오류가 있는지 찾는 것도 엔지니어가 해야 할 중요한 일이지요.

자바에는 Exception, 즉 예외라고 불리는게 있습니다. 이 예외라는 것은 에러와 같다고 보기는 어렵습니다.
예를 들어서,

int number = 'A';

이렇게 number 변수에 문자 A를 넣어준다고 해서 이것이 틀렸다고 말할 수 있을까요? number를 출력하면 아스키코드로 변환된 값이 저장되어 나타날 것입니다.

이것을 틀렸다고 말하진 않습니다. 이처럼 예외도 에러와는 다른 개념으로 보는게 맞을 것입니다.

예외가 발생하는 경우

그렇다면 어떤 경우에 예외가 발생할까요? 수많은 경우가 있겠지만 쉽게 풀어서 이야기해보면

  1. 숫자가 입력되어야 할 곳에 문자가 입력된 경우
  2. 배열의 범위가 초과되어 사용되는 경우
  3. 클래스를 사용하고자 호출했으나 존재하지 않을 때
  4. 파일을 어떤 위치에서 불러오려 했으나 그 위치에 존재하지 않을 때

이러한 경우 이외에도 예외가 발생하는 경우는 많습니다. 그것을 다 외우기보다 그때그때 찾아가며 왜 예외가 발생하였는지 살펴보면 되겠습니다.

예외 vs. 에러

그렇다면 예외와 에러의 결정적인 차이점은 무엇일까요? 에러는 발생하게 되면 코드를 아무리 멋있게 작성했다고 해도 실행할 수가 없습니다. 그렇지만 예외는 예외처리(Exception Handling)를 통해 프로그램이 정상적으로 실행되게 할 수 있습니다.

프로그램 실행 예외의 종류

NullPointerException

이 예외는 자바로 프로그래밍을 할 때 가장 많이 볼 수 있습니다. 이것은 객체의 참조가 없는 상태를 말하며 다음과 같은 예시가 있습니다.

String str = null;
System.out.print(str);

// Exception in thread "main" java.lang.NullPointerException
//	...

ArrayIndexOutOfBoundsException

앞에서 예를 든 배열의 범위가 초과되어 사용되는 경우입니다.

int[] array = { 1, 2, 3 };
System.out.println(array[3]);

// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
//	...

인덱스가 0부터 2까지인 배열에서 3번째 요소를 보여달라고 한다면 없는 걸 어떻게 찾냐며 자바 컴파일러가 화를 낼 것입니다.

이처럼 배열의 범위를 초과하는 경우에 나타나는 예외 객체 입니다.

NumberFormatException

자바는 문자열로 되어있는 데이터를 숫자로 변경할 때가 있습니다. 우리는 이전에 메서드를 살펴볼 때 parseInt()parseDouble() 메서드를 통해 문자열을 정수형이나 실수형으로 바꿔주었습니다. 그러나 숫자로 변환될 수 없는 문자열을 바꿔달라고 하면 자바 컴파일러는 또 화를 냅니다.

String intString = "5";
String fuck = "100+fifty";
		
int value1 = Integer.parseInt(intString);
int value2 = Integer.parseInt(fuck);
		
System.out.println(value1);
System.out.println(value2);

// Exception in thread "main" java.lang.NumberFormatException
//	...

예를 들어서 이런 코드가 있다고 가정할 때 변수 intStringparseInt() 메서드를 사용했을 때 정수형으로 반환해주지만 fuck처럼 되어있는 꼴은 정수형으로 바꿔주지 못합니다.

그래서 발생하는 예외가 NumberFormatException입니다.

이처럼 다양한 예외객체가 있는데 나오는 것을 모두 외울 수는 없으므로 그때그때 찾아보며 공부하도록 합시다!

예외처리 하기

자 그렇다면 예외가 발생하는 구문에 대해서는 우리가 어떤 조치를 취해줘야 하겠죠?

이 때 우리는 try...catch~문을 사용할 수 있습니다. 예외가 발생할 가능성이 있는 코드를 두고 예외 클래스의 메시지를 출력해주는 방법입니다.

// 예외 처리할 때 쓰는 try catch문 구조

try {
  // 예외가 발생할 가능성이 있는 소스코드
} catch (예외 클래스 e) {
  // 예외 클래스 메시지 출력
}		:
		:
        	:
        // catch는 연달아서 계속 쓸 수 있습니다.
} finally {
  // 무조건 실행할 구문
  // 뒤처리
}

우선 try에는 예외가 발생할 가능성이 있는 코드를 넣습니다. 여기에서 예외가 발생하지 않으면 catch를 건너 뛰고 finally에 있는 코드를 실행합니다.
만약 try에서 예외가 발생한다면, 더 이상 코드를 실행하지 않고 catch로 넘어가게 됩니다. 그곳에서 예외 처리 코드를 실행한 후 finally로 넘어가는데 finally는 무조건 실행하는 구문이지만 옵션일 뿐이며 생략할 수 있습니다.

그렇다면 예외 처리를 직접 해보겠습니다.

위에서 예시를 들었던 코드를 가져와보겠습니다.

String intString = "5";
String fuck = "100+fifty";
		
int value1 = Integer.parseInt(intString);
int value2 = Integer.parseInt(fuck);
		
System.out.println(value1);
System.out.println(value2);

여기에서 에러가 발생할만한 코드는 무엇일까요? 아무래도 각각의 문자열을 정수로 처리하는 과정이 아닐까 싶습니다.
그래서 try로 그 부분을 감싸줍니다.

String intString = "5";
String fuck = "100+fifty";

try {
  int value1 = Integer.parseInt(intString);
  int value2 = Integer.parseInt(fuck);
}
		
System.out.println(value1);
System.out.println(value2);

그 다음은 catch에 예외처리를 해주어야 합니다. NumberFormatException 예외였기 때문에 catch 옆에 소괄호를 열고 넣어줍시다.

String intString = "5";
String fuck = "100+fifty";

int value1 = 0;
int value2 = 0;

try {
  value1 = Integer.parseInt(intString);
  value2 = Integer.parseInt(fuck);
} catch (NumberFormatException e) {
  System.out.println("값을 정수로 바꿀 수 없습니다. 다시 시도해주세요.");
}
		
System.out.println(value1);
System.out.println(value2);

// 값을 정수로 바꿀 수 없습니다. 다시 시도해주세요.
// 5
// 0

우선은 try catch문의 스코프 안에 들어가면 전역변수로 사용할 수 없으므로 바깥에서 값을 초기화 해주고 각각 parseInt() 메서드를 사용해서 변환할 값을 넣어줍니다.

그러면 검사를 할겁니다. value2를 정수로 바꾸려고 하는데,,, 어?? 안된다! 라고 인지한 컴파일러가 catch문을 실행해줍니다.

함수에 예외처리 적용하기

만약 다음과 같은 함수가 있다고 가정해봅시다.

public static void method() {
  int[] num = { 1, 2, 3 };
  for (int i = 0; i < 4; i++) {
    System.out.println(num[i]);
  }
}

// 1
// 2
// 3
// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
//	...

배열안에 3개의 숫자 즉 0번째부터 2번째까지 숫자가 들어있고, 반복문을 돌려 4번 인덱스까지 돌게하는데 아쉽지만 우리가 만들어준 배열은 2번인덱스까지만 있기 때문에 2번 인덱스까지는 잘 출력해주다가 그 이후에 분명히 예외가 발생합니다.

함수의 경우에는 throws + 예외 클래스명을 써서 예외처리를 해줄 수 있습니다. 이렇게요!

public static void method() throws ArrayIndexOutOfBoundsException {
  int[] num = { 1, 2, 3 };
  for (int i = 0; i < 4; i++) {
    System.out.println(num[i]);
  }
}

파일 입출력


특정 위치의 파일 목록을 가져오는 방법 : list(), listFiles(), isFile(), isDirectory()

우선 File 파일이라고 하는 것은 데이터를 저장해는 매체 또는 매개체라고 정의합니다. Database 즉 파일을 입출력하기 위해 존재하고 근본이 되는것은 text파일입니다.

파일을 특정 위치에서 가져오기 위해서는 File이라는 객체를 사용합니다.

import java.io.File;
import java.io.IOException;

public class Main {
  
  public static void main (String[] args) {
  
    File file = new File("/Users/user");
    
  }
  
}

이렇게 File 객체에 file이름으로 변수를 선언할겁니다. 그런데 이제 생성자를 사용해서 파일 객체를 만들고 이는 Users/user라는 경로에 있는 폴더를 지정했습니다.

그렇다면 지정해준 경로 안에 있는 것들을 다 끄집어서 콘솔에 보여주겠습니다.

import java.io.File;
import java.io.IOException;

public class Main {
  
  public static void main (String[] args) {
  
    File file = new File("/Users/user");
    
    String[] fileList = file.list();	// fileList 배열은 File 객체로 만든 file을 리스트로 보여줍니다.
    
    for (int i = 0; i < fileList.length; i++) {
      System.out.println(fileList[i]);
    }
    
  }
  
}

그러면 폴더와 파일로 각각 나눠서 출력해보겠습니다.

File fileList[] = file.listFiles();		// listFiles() 메서드는 지정한 경로의 파일들을 리스트화 해줍니다.

for (int i = 0; i < fileList.length; i++) {

  if (fileList[i].isFile()) {			// fileList의 i번째 요소가 파일인 경우
  
    System.out.println("[파일]" + fileList[i].getName());
    
  } else if(fileList[i].isDirectory()) {	// fileList의 i번째 요소가 폴더인 경우
  
    System.out.println("[폴더]" + fileList[i].getName());
    
  }
}

파일을 생성하는 방법 : createNewFile()

File 객체의 메서드로 파일을 만들어줄 수도 있습니다.

File newFile = new File("/Users/user/myFolder/newFile.txt");

이렇게 경로를 우선 지정해주고 .createNewFile() 메서드를 사용해줄겁니다.

File newFile = new File("/Users/user/myFolder/newFile.txt");

if(newFile.createNewFile()) {
  System.out.println("파일을 성공적으로 만듦");
} else {
  System.out.println("파일 생성 실패");
}

자 그런데 이렇게만 작성하면 예외가 발생할 수 있습니다. 그래서 위에서 살펴봤던 try catch를 사용해 줄 것입니다.

File newFile = new File("/Users/user/myFolder/newFile.txt");

try {
  if(newFile.createNewFile()) {
    System.out.println("파일을 성공적으로 만듦");
  } else {
    System.out.println("파일 생성 실패");
  }
} catch (IOException e) {
  System.out.println("파일을 생성하지 못했습니다!");
}

이렇게 해주면 myFolder에 newFile이라는 텍스트 파일이 생겨있습니다.

폴더를 생성하는 방법 : mkdir()

폴더 또한 파일을 생성하는 방법과 아주 비슷합니다. 메서드만 달라질 뿐이죠.

파일은 createNewFile() 메서드를 사용했다면 폴더는 mkdir() 메서드를 사용합니다. make directory의 약어로 보시면 됩니다.

File newDir = new File("/Users/hwangduil/myfile/newdir");

try {
  if(newDir.mkdir()) {        // 여러개 만들때는 mkdirs()
    System.out.println("폴더 생성 성공!");
  } else {
    System.out.println("폴더 생성 실패");
  }
} catch (Exception e) {
  System.out.println("폴더를 생성하지 못했습니다");
}

폴더안의 폴더, 아니면 여러 폴더를 만들고 싶을 때는 mkdir()이 아니라 mkdirs()를 사용해야 합니다.

파일 존재여부 확인하는 방법 : exists()

파일의 존재여부는 exists() 메서드로 확인합니다.

if(newFile.exists()) {
  System.out.println("newFile.txt가 존재합니다.");
} else {
  System.out.println("newFile.txt가 존재하지 않습니다.");
}

이렇게 if문에 선언한 파일이 있는지 boolean값으로 반환하여 참거짓을 판별해줍니다.

읽기 전용으로 만들기와 파일 삭제하기 : setReadOnly(), delete()

파일을 읽기 전용으로 만들기 위해서는 파일을 선언해준 변수에 setReadOnly()를 해주는 것만으로도 파일이 읽기전용으로 바뀝니다.

그리고 마찬가지로 파일을 선언해 준 변수명에 delete()를 해주는 것 만으로도 파일이 삭제됩니다.

우리는 앞에서 텍스트 파일을 하나 만들었고 그 파일의 이름은 newFile이었습니다.

newFile.setReadOnly();		// 읽기전용으로 전환
newFile.delete();		// 파일 삭제

파일 쓰기 가능여부 조회하기 : canWrite()

파일이 읽기 전용이라면 쓰기는 못하겠지요? 사전에 확인하려면 canWrite() 메서드를 사용할 수 있습니다. 마찬가지로 boolean값으로 반환되기 때문에 if문에 써보았습니다.

if(newFile.canWrite()) {
  System.out.println("쓰기 가능합니다.");
} else {
  System.out.println("쓰기가 불가능합니다.");
}

파일 읽기


파일 안의 내용을 읽어들일 수도 있습니다. 방법으로는 한글자씩 읽는 방법과 문장으로 읽어주는 방식이 있는데, 하나씩 살펴보겠습니다.

한 글자씩 읽기

File file = new File("/Users/user/myFolder/newFile.txt");

FileReader fr = new FileReader(file);		// FileReader는 character 파일 읽기 기능을 제공합니다.

// 한글자씩 읽기
int ch = fr.read();		// 1개 음절단위로 읽어줌, 정수형(아스키코드)으로 자료형 변환

while (ch != -1) {		// ch != -1은 파일 끝까지 도달하지 않은 경우를 의미
  System.out.println((char)ch);	// 아스키코드를 문자로 바꿔줌
  ch = fr.read();		// 초기화
}

fr.close();		// 작업이 끝나면 반드시 close로 끝내줘야함.

그런데 이렇게만 작성하면 예외가 발생하므로 try catch를 사용해주겠습니다.

File file = new File("/Users/user/myFolder/newFile.txt");

try {
  FileReader fr = new FileReader(file);		// FileReader는 character 파일 읽기 기능을 제공합니다.

  // 한글자씩 읽기
  int ch = fr.read();		// 1개 음절단위로 읽어줌, 정수형(아스키코드)으로 자료형 변환

  while (ch != -1) {		// ch != -1은 파일 끝까지 도달하지 않은 경우를 의미
    System.out.println((char)ch);	// 아스키코드를 문자로 바꿔줌
    ch = fr.read();		// 초기화
  }

  fr.close();		// 작업이 끝나면 반드시 close로 끝내줘야함.
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

자 그런데 catch 쪽이 많이지면 코드가 간결하지 못해서 좀 그렇겠죠?? Exception을 하나로 퉁쳐서 쓰는 방법이 있습니다. 바로 catch (Exception e) {... }처럼 써주는 것이죠!

그러면 catch를 하나로 끝낼 수 있습니다.

catch절 하나로 퉁치기

File file = new File("/Users/user/myFolder/newFile.txt");

try {
  FileReader fr = new FileReader(file);		
  int ch = fr.read();		
  while (ch != -1) {		
    System.out.println((char)ch);
    ch = fr.read();
  }
  fr.close();
} catch (Exception e) {
  e.printStackTrace();
} 

이렇게 해서 출력을 해주면, newFile에 Hello라고 입력되어 있다고 가정할 때,

H
e
l
l
o

처럼 한글자씩 개행을 하며 보여줄 것입니다.

한 문장씩 읽기

그렇다면 문장 통째로 읽을 수는 없을까요? 물론 가능합니다. 그런데 문장을 통째로 읽으려면 위에서 했던 FileReader로는 할 수 없기 때문에 BufferedReader를 사용해 주어야 합니다.

우리가 입력을 받아서 값을 저장할 때 Scanner라는 것을 자주 사용했었습니다.

그런데, 이 ScannerBufferedReader의 결정적인 차이점이 하나 있는데, Scanner는 스페이스바를 입력하게 되면 이를 문자열로 인식하지 못해서 끝났다고 처리합니다.

예를 들어서 "Hello World"라고 Scanner에 입력한다면 Scanner는 Hello까지밖에 인식하지 못합니다.

그러나 BufferedReader를 사용하면 스페이스바를 문자열로 취급하기 때문에 문장 자체를 통째로 읽어들일 수가 있는것이죠..

파일에서 문장을 읽어오는 예시를 보여드리겠습니다.

File file = new File("/Users/user/myFolder/newFile.txt");

BufferedReader br = new BufferedReader(new FileReader(file));	// 파일리더로 파일을 읽어주고 이를 BufferedReader로 또 읽어줍니다.

String str;

while((str = br.readLine()) != null) {	// readLine()은 텍스트 파일을 한 줄씩 읽어서 리턴
  System.out.println(str);
}

br.close();		// 마지막 close는 필수

그러나 이렇게만 또 작성해주면 예외가 발생하기 때문에 try catch로 묶어주겠습니다.

try {
  File file = new File("/Users/user/myFolder/newFile.txt");

  BufferedReader br = new BufferedReader(new FileReader(file));	// 파일리더로 파일을 읽어주고 이를 BufferedReader로 또 읽어줍니다.

  String str;

  while((str = br.readLine()) != null) {	// readLine()은 텍스트 파일을 한 줄씩 읽어서 리턴
    System.out.println(str);
  }

  br.close();		// 마지막 close는 필수
} catch (Exception e) {
  e.printStackTrace();
}

파일 쓰기


파일 읽기가 가능하다면, 쓰기도 가능할 것입니다. 물론 읽기전용이 아닌 파일에 한해서요.

쓰기에서는 보통의 normal한 쓰기, 추가 쓰기, 개행이 이루어지는 문장쓰기를 살펴 볼 것입니다.

일반적인 쓰기

만들어진 문서 안에 지정한 내용을 쓸 수 있게 해줍니다.

File file = new File("/Users/user/myFolder/newFile.txt");

try {
  FileWriter fw = new FileWriter(file);	// file 객체 FireWriter로 뭔가 내용을 쓰겠다.
  
  fw.write("안녕하세요");	// write() 메서드로 문서에 뭔가 쓸 수 있다.
  fw.write("반가워요");
  
  fw.close();		// close 필수
} catch (Exception e) {
  e.printStact.Trace;
}

추가 쓰기

기존에 작성된 내용에 추가로 더욱 작성하고 싶을 때, 일반적인 쓰기 방법을 사용하면 파일이 덮어쓰여지므로 기존에 작성한 내용들은 모두 사라집니다.

그래서 추가로 내용을 넣고 싶을 때에는 FireWriter 매개변수로 파일과 boolean값을 추가로 전달해줍니다.

booleantrue일 때 내용을 추가해서 적어줄 수 있습니다.

File file = new File("/Users/user/myFolder/newFile.txt");

try {
  FileWriter fw = new FileWriter(file, true);	// 여기에 true로 지정해서 추가 쓰기
  
  fw.write("건강하세요");
  fw.write("행복하세요");
  
  fw.close();
} catch (Exception e) {
  e.printStact.Trace;
}

개행이 이루어지는 쓰기

일반적인 쓰기와 추가 쓰기는 문장단위로 쓸 수 있긴 하지만 파일을 열어보면 문장들이 다닥다닥 붙어있습니다. 아주 보기 안좋아요!

그래서 개행을 통해서 문장을 구별해 줄 수 있으면 참 좋겠죠

개행을 하기 위해서는 준비해야될 준비물이 세가지 있습니다. FileWriter, BufferedWriter, PrintWriter 이렇게 세개가 필요해요..

자 그러면 어떻게 사용하는지 살펴볼게요.

File file = new File("/Users/user/myFolder/newFile.txt");

try {
  FileWriter fw = new FileWriter(file);
  BufferedWriter bw = new BufferedWriter(fw);
  PrintWriter pw = new PrintWriter(bw);
  
  pw.println("안녕하세요");
  pw.println("만나서 반가워요");
  pw.println("잘 부탁합니다");
  
  // close필수, 안쪽부터 바깥쪽 순으로 close
  pw.close();
  bw.close();
  fw.close();
} catch (Exception e) {
  e.printStackTrace();
}

이렇게 작성 후 실행한 결과를 확인해보면 각 문장들이 개행되어 저장된것을 볼 수 있습니다.

오늘 정리할 내용은 여기까지입니다.

그러면 연습문제를 통해 마무리 복습을 해보겠습니다.


연습문제

문제 1

학생 세명의 이름이 담긴 배열이 주어진다. 이 배열의 각 원소를 개행하여 파일에 기록하고, 파일에서 다시 가져와서 콘솔에 나타내시오.

import java.io.*;

public class Main {

	public static void main (String[], args) {
    	
        String name[] = { "성춘향", "일지매", "홍길동" };
        
        // 파일 생성 장소 결정
        File file = new File("/Users/user/myfile/names.txt");
        
        try {
        	// 개행해서 파일에 기록
        	FileWriter fw = new FileWriter(file);
        	BufferedWriter bw = new BufferedWriter(fw);
        	PrintWriter pw = new PrintWriter(bw);
        
        	for (int i = 0; i < name.length < i++) {
          		pw.println(name[i]);
        	}
        
        	pw.close();
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        // 콘솔로 가져오기
        String[] names = null;
        int count = 0;
        String str;
        
        try {
        	BufferedReader br = new BufferedReader(new FileReader(file));
            
            while((str = br.readLine()) != null) {
            	count++;
            }
            
            names = new String[count];
            int n = 0;
            br = new BufferedReader(new FileReader(file));	// 초기화(처음부터 다시 읽기)
            while((str = br.readLine()) != null) {
            	names[n] = str;
                n++;
            }
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        for (int i = 0; i < names.length; i++) {
        	System.out.println(names[i]);
        }
        
    } 
}

문제 2

배열에 사람 이름, 나이, 거주지가 주어진다. 이 때 텍스트 파일에 이 정보를 저장하고 다시 정보를 가져봐 배열의 형태로 나타내시오. 단, 텍스트 파일에는 "이름-나이-거주지"의 형태로 작성하고, 배열은 [이름, 나이, 거주지] 형태로 콘솔에 출력한다. 또한 println은 한번만 사용한다.

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

public class Main {

	public static void main (String[], args) {
    
    	String[] human = { "홍길동", "24", "서울시" };
        
        // 파일 위치 선정
        File file = new File("/Users/user/myfile/human.txt");
        
        try {
        	// PrintWriter 객체 생성
        	PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)))
            
            String str = human[0] + "-" + human[1] + "-" + human[2];	// 토큰을 넣어서 자르기 쉽게
            
            pw.println(str);
            pw.colse();
        
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        String hum = "";
        
        try {
        	BufferedReader br = new BufferedReader(new FileReader(file));
            String str1;
            
            while((str1 = br.readLine()) != null) {
            	hum = str1;
            } 
            br.close();
            
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        String[] split = hum.spilt("-");
        
        System.out.println(Arrays.toString(split));
        
    }

}
profile
tried ? drinkCoffee : keepGoing;

0개의 댓글