-
자바의 I/O 스트림Java 2023. 3. 2. 16:47
입출력 스트림
네트워크에서 자료의 흐름이 물의 흐름과 같다고 해서 입출력 스트림으로 불린다.
입출력이 구현되는 곳 : 파일 디스크,키보드,마우스,네트워크(통신),메모리
(System.in 과 System.out도 각각 키보드와 모니터를 나타내는 스트림으로 입력 스트림과 출력 스트림으로 불린다)
입출력 스트림의 구분
대상 기준 : 입력 스트림 / 출력 스트림
자료의 종류 : 바이트 스트림/ 문자 스트림
바이트 스트림 : 8비트의 바이트 단위로 입출력을 수행하는 스트림
문자 스트림 : 입출력 단위가 문자인 스트림
입출력 스트림 예제
package ch01; import java.io.IOException; public class SystemInTest1 { public static void main(String[] args) { //키보드에서 데이터를 프로그램 안으로 넣기 System.out.println("알파벳 하나 쓰고 Enter를 누르세요."); int i; // 한 바이트씩 키보드에 값을 입력받아 읽어라 try { //입력 i = System.in.read(); //출력 System.out.println(i); // 인코딩 - 컴퓨터에는 문자를 쓰기위해서 문자표가 미리 저장된게 있음(미리 약속) -> 정수값을 문자열로 변환하는것 System.out.println((char)i); //ab를 입력할때 a만 출력한다 - 기반 스트림 //한글을 입력하니까 문자가 깨짐 (영어는 1byte안에 표현이 다되지만 한글이나 다른 언어로 표현할려면 byte를 늘려야한다) //그러므로 유니코드로 재정의하여 문자를 연출한다. (utf-8, utf_16) } catch (IOException e) { e.printStackTrace(); } } //end of main } //end of class
package ch01; import java.io.IOException; public class SystemInTest2 { public static void main(String[] args) { System.out.println("알파벳 여러개를 쓰고 엔터를 눌러 주세요."); int i; try { //i= System.in.read(); //한번 수행 되는 코드 -> 엔터키(\n)를 누를때까지 반복해보자. //(괄호 안에는 식을 작성할 수 있다) while( ( i=System.in.read() ) != '\n' ) { //화면에 출력 System.out.println("i : " + i ); System.out.println("인코딩 : " + (char)i); } } catch (IOException e) { e.printStackTrace(); } } //end of main } //end of class
FileInputStream 예제
package ch02; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStreamTest1 { public static void main(String[] args) { FileInputStream fis = null; try { //오류가 안나면 우리코드가 스트림이 연결 되었다는 뜻 fis = new FileInputStream("input.txt"); //int temp = fis.read(); //System.out.println(temp); //System.out.println((char)temp); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); System.out.println((char)fis.read()); //IOException = FileNotFoundException보다 상위 클래스 } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } //비정상 처리 했기 때문에 코드가 옴 System.out.println("여기 코드가 올까요?"); } //end of main } //end of class
출력값 h e l l o w o r l d 여기 코드가 올까요?
여기서 read()는 하나의 바이트를 읽을때 사용한다는것을 알수있고 read()는 int값을 반환한다.
read()는 int 값을 반환형으로 해야만 입력 스트림의 끝을 표시하는데 -1을 사용할 수 있다. (바이트가 아닌 이유)
즉 위의 코드를 반복문으로 사용할 시에 read()값이 -1을 반환하면 멈추게 된다.
응용코드는 다음과 같다.package ch02; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStreamTest2 { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("input.txt"); int i; // 파일은 마지막에 읽을 값이 없다면 -1 를 반환한다. System.out.println(">> 기사 시작 <<"); while( (i = fis.read()) != -1 ) { System.out.print((char)i); } System.out.println("\n"+">> 기사 종료 <<"); } catch (FileNotFoundException e) { System.out.println("파일을 찾을 수 없어요."); } catch (IOException e) { System.out.println("입력 스트림 동작시 오류 발생 했네요."); }finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); //프로그램 종료 } } } //end of main } //end of class
FileOutputStream 예제
package ch03; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream1 { public static void main(String[] args) { // 현재 output.txt 파일은 없는 상태 (맨 처음) FileOutputStream fos = null; try { fos = new FileOutputStream("output.txt"); fos.write(97); fos.write(98); fos.write(99); fos.write(100); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } //end of main } //end of class
하나의 바이트를 쓸때는 write()를 쓴다.
output.txt에 abcd가 찍히는것을 확인할수 있다.
조금 더 응용을 해서 배열에 값을 반복문을 통해 넣어 A부터 Z까지 쓸수있다.
다음 코드를 보자package ch03; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream2 { public static void main(String[] args) { //output3.txt // hello world 를 찍어주세요 FileOutputStream fos = null; // 파일이 없다면 FilerOut... 파일을 먼저 생성해 준다. try { byte[] bs = new byte[26]; byte myData = 65; fos = new FileOutputStream("output2.txt"); // 파일에다가 A ~ Z 까지 알파벳을 출력하고 싶다면 코드 작성 방법은 ?? //반복 횟수가 정해져 있다면 - for문 for(int i = 0; i < bs.length; i++) { fos.write(myData); myData++; //65 - A , 66 - B } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } //end of main } //end of class
여기에서 조금더 응용을 해보자면 true,false 를 응용하여 추가적으로 글을 쓰게 하거나 기존에 있던거를 삭제하고 다시 쓰는 코드를 짜보자.
package ch03; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream4 { public static void main(String[] args) { //output3.txt // hello world 를 찍어주세요 FileOutputStream fos = null; // 파일이 없다면 FilerOut... 파일을 먼저 생성해 준다. try { byte[] bs = new byte[26]; byte myData = 65; fos = new FileOutputStream("output2.txt", true); //true라고 적게 되면 추가적으로 글을 쓰는 동작을 하게되고 false라고 쓰면 기존에 있던거를 삭제하고 다시 쓴다. // 파일에다가 A ~ Z 까지 알파벳을 출력하고 싶다면 코드 작성 방법은 ?? //반복 횟수가 정해져 있다면 - for문 for(int i = 0; i < bs.length; i++) { //fos.write(myData); bs[i] = myData; myData++; //65 - A , 66 - B } fos.write(bs); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } //end of main } //end of class
FileReader 예제
package ch04; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class FileReaderTest1 { public static void main(String[] args) { //문자 단위로 읽어 들이는 스트림 FileReader fr = null; try { fr = new FileReader("output2.txt"); int temp = fr.read(); //Reader는 최소 2바이트를 읽어서 한글이 안깨지게끔 해준다. System.out.println("temp : " + (char)temp); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //end of main } //end of class
FileReader는 한글자씩 읽을때 쓰이며 위에서 설명한것과 동일하게 read() int값을 반환하며 끝이 -1이 반환된다. 그러므로 위의 코드와 같이 한글자씩 읽는것을 응용하여 반복문을 써서 읽을 수 있다. 아래의 코드를 보면서 이해하자.
package ch04; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class FileReaderTest2 { public static void main(String[] args) { //문자 단위로 읽어 들이는 스트림 //Reader는 최소 2바이트를 읽어서 한글이 안 깨지게끔 읽어준다. FileReader fr = null; try { fr = new FileReader("output2.txt"); // - 1 int i; while( ( i = fr.read()) != -1 ) { System.out.println((char)i); } int temp = fr.read(); System.out.println("temp : " + (char)temp); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //end of main } //end of class
FileWriter 예제
package ch04; import java.io.FileWriter; import java.io.IOException; public class FileWriterTest1 { public static void main(String[] args) { FileWriter fw = null; char[] buf = {'반','갑','습','니','다'}; try { fw = new FileWriter("writer1.txt"); //fw.write("H"); //문자 하나만 출력 --> File //fw.write(buf); // 문자 배열로 파일에다가 출력 //대상 , 인덱스 시작값, 길이 값 fw.write(buf, 1, 3); } catch (IOException e) { e.printStackTrace(); }finally { try { fw.close(); //프로그램 종료 } catch (IOException e) { e.printStackTrace(); } } } }
배열값에 담겨있는 인덱스1번부터 3번까지 writer1.txt에 ' 갑습니 '가 쓰여져 있는것을 알수있다.
응용문제
package ch04; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Myarticle2 { public static void main(String[] args) { //파일 입출력을 활용해서 코드를 작성해 주세요. //입력 대상 : article1.txt //출력 대상 : today_article.txt FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("article1.txt"); fw = new FileWriter("today_article.txt"); // 더이상 읽을게 없다면 -1 을 리턴한다. // Reader 기반은 2바이트 이상 처리 가능하다 -> 한글이 깨지지 않아요. int i; fw.write("MVC 뉴스"+"\n"); while(( i = fr.read()) != -1) { //System.out.print((char)i); fw.write(i); } fw.write("\n"+"작성자 : 홍길동"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { fr.close(); fw.close(); //사전 기반 지식 //Writer를 작성할 때 스트림이 열러 있으면 잠시 버퍼 공간에 담아 두었다가 // 스트림이 종료 되거나 flush 메서드를 만나면 실제로 file에 출력한다. } catch (IOException e) { e.printStackTrace(); } } } //end of main } //end of class