[Java] 파일 입출력

Junseo Kim·2019년 12월 19일
0

[Java]자바 기초

목록 보기
12/35

try catch

파일 입출력 시, try catch가 중요하다

  • 프로그램 실행 시, 오류가 발생하면 그 오류에 대한 대처를 할 수 있게 해주는 것
  • 에러가 발생한 정확한 위치 파악. 상세 정보
  • catch구문은 여러개 사용가능. Exception의 종류도 많음

<기본 형태>

try{

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

try안에서 짠 구문에서 에러가 발생하면, catch안에 있는 것들이 실행되며 에러를 뿌려줌

파일 입출력

  • 하드디스크나 ssd에 실제로 파일을 저장하는 것
  • 스트림 단위(바이트 단위)로 데이터를 나눠 사용한다

데이터를 파일로 저장

데이터를 내보낼 때는, OutputStream을 사용한다. OutputStream이란 내보낸다는 의미이다.

ex. h, e, l, l, o 라는 5개의 데이터가 들어있는 배열을 OutputStream을 통해 파일로 저장한다.
파일로 저장해야하므로 FileOutputStream을 사용한다.

public static void main(String[] args) {
		
	byte data[]= {'h','e','l','l','o'};
		
	OutputStream save = new FileOutputStream("경로\\파일명");
}

위와 같이 하면 에러가난다. FileOutputStream을 사용할 땐 throws나 try catch를 사용해주어야한다. trycatch를 사용하면 아래와같은 모양이된다.
Tip) 현재는 OutputStream을 FileOutputStream으로 생성했는데, 이것이 가능한 이유는 FileOutputStream이 OutputStream을 상속하고 있기 때문이다. 원래는 타입을 맞춰주는것이 일반적이다.

public static void main(String[] args) {
		
	byte data[]= {'h','e','l','l','o'};
		
	try {
		FileOutputStreamsave = new FileOutputStream("/Users/kimjunseo/Desktop/hello.txt");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}
}

Tip) FileNotFoundException대신 IOException을 사용해도 된다. IOException은 파일 입출력에 대한 에러를 한번에 다루는 것이다.

실제로 파일을 써줄때는 OutputStream의 write를 사용한다. for문을 사용하여, 한 글자씩 파일에 쓴다.
Tip)write를 사용할 땐, IOException을 사용해주어야한다.
Tip)파일 스트림을 쓰고 난 후, 닫아줘야한다.

	public static void main(String[] args) {
		
		byte data[]= {'h','e','l','l','o'};
		
		try {
			FileOutputStream save = new FileOutputStream("/Users/kimjunseo/Desktop/hello.txt");
			for(int i=0;i<data.length;i++) {
				save.write(data[i]);
			}
            save.close(); // 파일스트림을 쓰고 난 후, 닫아줘야한다.
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

지정한 경로에, 지정해준 파일이름으로 파일이 생기고, 파일 내용에 hello가 적힌걸 볼 수 있다.

Tip) 문자열을 byte로 변환하여 위와 같은 형식으로 저장할 수도 있다. String을 getBytes()를 사용하면 byte 배열에 넣어줄 수 있다.

	public static void main(String[] args) {
		
		String data2 = "hello world";
		byte data[]= data2.getBytes();
		
		try {
			FileOutputStream save = new FileOutputStream("/Users/kimjunseo/Desktop/hello.txt");
			for(int i=0;i<data.length;i++) {
				save.write(data[i]);
			}
            save.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

파일 읽어오기

파일을 읽어와 실행한 프로그램의 메모리 상에 입력하는 것이다. InputStream을 이용한다.

Tip)파일에서 읽어와야하기 때문에 FileInputStream을 사용한다.
Tip)저장할때와 마찬가지로 trycatch를 사용한다.
Tip)저장할때와 마찬가지로 FileInputStream이 InputStream을 상속하고 있으나, 타입을 맞춰 적어주는 것이 일반적이다.

ex.

	public static void main(String[] args) {
		
		try {
			//InputStream read = new FileInputStream("/Users/kimjunseo/Desktop/hello.txt"); 
            FileInputStream read = new FileInputStream("/Users/kimjunseo/Desktop/hello.txt"); // 일반적으로는 타입을 맞춰줌
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

파일을 불러올때, 내용물을 모를 수도 있기 때문에 파일의 크기를 알아야한다. InputStream의 available()을 사용하여 크기를 알 수 있다. for문을 사용하여 하나씩 읽어온다. 데이터를 읽을 때는 InputStream의 read()를 사용한다.

Tip) 자바에서는 String을 다룰때, String 값 + 알파를 하면, 뒤의 알파도 String화 된다.

	public static void main(String[] args) {
		
		try {
			FileInputStream read = new FileInputStream("/Users/kimjunseo/Desktop/hello.txt"); // 읽어올 파일 경로와 위치 
            
			int filesize = read.available(); // 파일 내용물의 크기 읽어옴 
			
            String data="";
			for(int i=0;i<filesize;i++) {
            	data += (char)read.read(); // InputStream의 read()를 사용하여 데이터를 읽어옴. 
                						   //but, (char)이 없을 경우 숫자로 읽어와진다. 따라서 (char)을 붙여주어 형변환 시켜준다. 
                                           //(char)read.read()는 char 타입이지만, 자바에서는 String을 다룰 때, 
                                           //String + 알파를 하는 경우, 뒤의 알파도 자동으로 String으로 변환시켜서 사용한다.
			}
			read.close(); //파일 스트림 사용 후에는 닫아주어야한다.
            System.out.println(data);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

한글다루기

위의 코드로 한글을 다루려고 하면, 저장은 올바르게 되지만, 읽어올 때, 제대로 읽어오지 못한다. 인코딩 문제 때문이다.

캐릭터인코딩을 지정 해주기 위해서는 Reader을 사용해야한다.(InputStreamReader가 Reader를 상속하므로, Reader a = new InputStreamReader 꼴로 사용할 수 있지만, 일반적으로는 InputStreamReader a = new InputStreamReader 이런 식으로 타입을 맞춰준다.)

Tip)InputStreamReader는 InputStreamReader("input스트림","캐릭터set"); 이런식으로 사용한다.

ex.

	public static void main(String[] args) {
		
		try {
			FileInputStream read = new FileInputStream("/Users/kimjunseo/Desktop/hello.txt");  
            
            //InputStream read와, 한글을 지원하는 character set utf-8을 지정하여 InputStreamReader를 선언한다.
			InputStreamReader reader = new InputStreamReader(read, "utf-8");
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

값을 출력해보기 위해 BufferedReader(버퍼단위로 데이터를 처리)를 사용하여, InputStreamReader의 값을 옮겨온다.
readLine()을 사용해서 한 번에 읽는다.

	public static void main(String[] args) {
		
		try {
			FileInputStream read = new FileInputStream("/Users/kimjunseo/Desktop/hello.txt");  
            
			InputStreamReader reader = new InputStreamReader(read, "utf-8");
			BufferedReader reader2 = new BufferedReader(reader); // reader가 읽은 데이터를 buffer에 올림 
			
			String data = reader2.readLine(); // 버퍼를 한 번에 읽음 
			System.out.println(data);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

0개의 댓글