데이터 입출력 : IO(Input/Output)
2022. 10. 7. 16:37ㆍDev.Program/Java & Spring
728x90
< 데이터 입출력 : IO(Input/Output) >
JAVA 책 p589
======== JAVA0703 프로젝트 만들기
======== Ex.java 만들기
- 표준 출력(모니터)
- java.io 패키지
- 표준 입력(키보드)
import java.io.IOException; import java.io.InputStream; public class Ex { public static void main(String[] args) { System.out.println("데이터를 입력하세요."); InputStream is = null; try { // System.in : 표준 입력(키보드)을 사용하여 데이터 입력받기 is = System.in; // => 키보드로부터 입력되는 모든 데이터를 InputStream 객체로 관리하게 됨 int n = is.read(); // 읽어들이는 데이터 중 1byte 만큼을 변수에 저장 System.out.println("입력 데이터 : " + n); } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
- 내가 입력한 문자 : abc
System.out.println("데이터를 입력하세요"); // try ~ resources 구문을 사용하면 별도의 close() 메서드를 호출하지 않아도 // 자동으로 작업이 끝난 후 close() 메서드를 호출하여 자원 반환해줌 try(InputStream input = System.in) { // int read = input.read(); // 1byte 데이터 읽어오기 // => 읽어올 데이터가 없으면 -1 리턴됨 int read = -1; while((read = input.read()) != -1) { // 읽어올 데이터가 없을 때 까지 1byte 씩 읽어오기 // 읽어들인 데이터 출력 System.out.println( "읽어들인 데이터 : " + read + ", 문자 변환 : " + (char)read); // 다음 1byte 읽어오기 // read = input.read(); } } catch (IOException e) { e.printStackTrace(); } |
- 위에 거 주석처리한 뒤 이걸로 바꾸기
- 13은 \r 커서를 맨 앞으로 이동
- 10은 \n 엔터키
자바 I/O(Input/Output)
* - java.io 패키지 사용 클래스들의 모음 * - 각종 입출력을 담당 * * 키보드로 데이터를 입력받는 방법 * 1. InputStream 객체를 사용하여 1byte 단위로 데이터를 처리하는 방법 * - read() 메서드를 사용하여 1byte 가져올 수 있음 * - 아무리 많은 데이터가 입력되어도 1byte 만 다룰 수 있기 때문에 * 더 많은 데이터나 더 큰 단위를 처리할 수 없음 * ⇒ 영문 또는 숫자 등 1글자만 입력 가능 * ⇒ 한글이나 한자 등 2byte(char 단위) 문자들 처리 불가능 * ⇒ 별도로 char 타입으로 형변환 필요 * - 가장 저수준의 입력 방법 |
======== Ex2.java
import java.io.IOException; import java.io.InputStream; public class Ex2 { public static void main(String[] args) { /* * 키보드로 데이터를 입력받는 방법 * 2. InputStream 객체를 사용하여 2byte 단위로 데이터를 처리하는 방법 * => byte 타입 배열을 활용하여 여러개의 byte 를 처리 * */ try(InputStream is = System.in) { // 5byte 단위로 데이터 처리를 위해 5byte 크기의 배열 생성 byte[] b = new byte[5]; int n = is.read(b); // read() 메서드 파라미터로 byte[] 배열 전달 System.out.println("입력된 데이터 갯수(byte 수) : " + n); // 반복문을 사용하여 byte[] 배열에 저장된 모든 데이터 출력 for(byte data : b) { System.out.println("입력 데이터 : " + data + ", 문자로 변환 : " + (char)data); } } catch (IOException e) { e.printStackTrace(); } } } |
- 내가 만든 배열 수 만큼만 나옴
// byte[] 타입 데이터(문자)들을 하나의 문자열로 결합하는 방법 // => String 객체 생성 => byte[] 배열, offset값(0), 읽어들일 크기(n) 전달 String str = new String(b, 0, n); System.out.println("문자로 변환 결과 : " + str); |
======== Ex3.java
- InputStream 객체 하나를 받아올 수 있다!
- 한번 쓰고 버려질거기때문에 바로 System.in 넣으면 됨
- 훨씬 깔끔해짐
- 근데 자원을 반환해야한다
- 리턴타입 : int ⇒ 별도로 또 형변환이 필요함
try(InputStreamReader reader = new InputStreamReader(System.in)) { int data = reader.read(); System.out.println("읽은 데이터 : " + data + ", 문자로 변환 : " + (char)data); } catch (IOException e) { e.printStackTrace(); } |
- 한글자 밖에 안나온다
// char 타입 배열을 사용하여 여러개의 문자 읽어오기 try(InputStreamReader reader = new InputStreamReader(System.in)) { char[] buffer = new char[10]; int n = reader.read(buffer); String str = new String(buffer, 0, n); System.out.println("읽은 데이터 : " + str); } catch (IOException e) { e.printStackTrace(); } |
- 단 열글자(배열 크기)를 넘어가면 또 잘림!
======== Ex4.java
- 원래는 이렇게 사용(데코레이션 패턴)
- 한 문장으로 만들기 가능! 실제로 이렇게 사용한다면 buffer.close() 적어줘야함
⇒ 그래서 try catch 문 안에 사용
try(BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in))) { // BufferedReader 객체로부터 한 문장(라인)을 읽어오기 String str = buffer.readLine(); System.out.println("읽어온 데이터 : " + str); } catch (IOException e) { e.printStackTrace(); } |
- 아무리 길어도 엔터키 전까지 전부 가져옴!
try(BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in))) { // BufferedReader 객체로부터 한 문장(라인)을 읽어오기 // String str = buffer.readLine(); // System.out.println("읽어온 데이터 : " + str); // 연속적으로 여러개의 문장을 읽어오기 => Ctrl + Z 입력 전까지 입력받기 // => Ctrl + Z : 정수로 치면 -1, 문자로 치면 null 이 전달됨 String str = buffer.readLine(); while(str != null) { System.out.println("읽어온 데이터 : " + str + "\n"); str = buffer.readLine(); // 다음 라인 입력받기 } } catch (IOException e) { e.printStackTrace(); } |
609p
614p
======== Ex5.java
> 파일 탐색기(D 드라이브)
temp 새폴더 만들기
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Ex5 { public static void main(String[] args) { /* p.614 * 자바의 기본 데이터 입출력 * - DataInputStream, DataOutputStream 객체 사용 * - 반드시 두 객체 간에만 데이터 입출력 * - 자바의 기본 데이터타입 8가지 + 문자열(String) 입출력 가능 * => readXXX() 과 writeXXX() 메서드 사용하며, XXX은 데이터 타입의 이름을 사용 * 주의! String 타입은 XXX 부분에 String 대신 UTF 사용 * ex) readUTF(), writeUTF() */ File f = new File("D:\\temp\\data.dat"); try(DataOutputStream dos = new DataOutputStream(new FileOutputStream(f))) { // DataOutputStream 객체를 사용하여 자바의 기본데이터타입 데이터 출력 // => 출력되는 데이터가 D 드라이브의 temp 폴더 내의 data.dat 파일에 기록됨 dos.writeInt(10); // 정수 출력 dos.writeDouble(3.14); // 실수 출력 dos.writeUTF("홍길동"); // 문자열 출력(writeString() 아니므로 주의!) } // catch (FileNotFoundException e) { // e.printStackTrace(); // } catch (IOException e) { e.printStackTrace(); } try(DataInputStream dis = new DataInputStream(new FileInputStream(f))) { // dos.readXXX() 메서드 호출하여 데이터 가져오기(입력) int num = dis.readInt(); double dNum = dis.readDouble(); String str = dis.readUTF(); // 입력받은 데이터 출력 System.out.println("int형 정수 : " + num); System.out.println("double형 실수 : " + dNum); System.out.println("String형 문자열 : " + str); } catch (IOException e) { e.printStackTrace(); } } } |
- 열어보면 알수없는 문자가 있음(그래서 DataInputStream / OutputStream으로만 출력하고 입력할수있다)
- 내보내는 순서 그대로 읽어와야함
======== Ex6.java
p616
// Person 클래스 정의 - 직렬 class Person implements Serializable { String name; int age; String jumin; public Person(String name, int age, String jumin) { super(); this.name = name; this.age = age; this.jumin = jumin; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", jumin=" + jumin + "]"; } |
- 클래스 정의
Person p = new Person("홍길동", 20, "901010-1234567"); File f = new File("D:\\temp\\serialPerson.dat"); // Person 객체를 외부 파일로 출력하기(= 직렬화) // => ObjectOutputStream 객체를 생성하여 출력스트림 객체 연결 // 파일로 내보내기 위한 출력 스트림은 FileOutputStream 객체 연결 try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f))) { // ObjectOutputStream 객체의 writeObject() 메서드를 사용하여 객체 출력 oos.writeObject(p); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } |
- 메인에서 객체생성 후 실행해보기
// 외부 파일(D 드라이브 - temp - serial_person.dat)에 저장되어 있는 // Person 객체를 ObjectInputStream 객체를 사용하여 읽어오기 try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f))) { // ObjectInputStream 객체의 readObject() 메서드를 사용하여 // 파일에 저장된 객체를 Object 타입으로 읽어오기 // => 리턴타입이 Object 타입이므로 실제 객체 사용을 위해 다운캐스팅 필요 Person person = (Person) ois.readObject(); // 리턴받은 객체 내의 멤버변수에 접근 // System.out.println(person.name + ", " + person.age + ", " + person.jumin); System.out.println(person); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } |
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Ex6 { public static void main(String[] args) { /* * 객체의 직렬화(Serialization) & 역직렬화(Deserialization) * - 자바에서 사용하는 객체를 영속성을 부여하여 * 파일이나 네트워크 등으로 내보내는 것을 직렬화라고 하며, * 반대로 파일이나 네트워크로부터 읽어들여 객체로 변환하는 것을 역직렬화라고 함 * - ObjectInputStream, ObjectOutputStream 클래스 사용 */ Person p = new Person("홍길동", 20, "901010-1234567"); File f = new File("D:\\temp\\serialPerson.dat"); // Person 객체를 외부 파일로 출력하기(= 직렬화) // => ObjectOutputStream 객체를 생성하여 출력스트림 객체 연결 // 파일로 내보내기 위한 출력 스트림은 FileOutputStream 객체 연결 try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f))) { // ObjectOutputStream 객체의 writeObject() 메서드를 사용하여 객체 출력 oos.writeObject(p); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // -------------------------------------------- // 외부 파일(D 드라이브 - temp - serial_person.dat)에 저장되어 있는 // Person 객체를 ObjectInputStream 객체를 사용하여 읽어오기 try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f))) { // ObjectInputStream 객체의 readObject() 메서드를 사용하여 // 파일에 저장된 객체를 Object 타입으로 읽어오기 // => 리턴타입이 Object 타입이므로 실제 객체 사용을 위해 다운캐스팅 필요 // Person person = (Person) ois.readObject(); // 리턴받은 객체 내의 멤버변수에 접근 // System.out.println(person.name + ", " + person.age + ", " + person.jumin); // System.out.println(person); // 형변환 전에 타입 체크를 수행할 경우 Object o = ois.readObject(); if(o instanceof Person) { Person person = (Person) o; System.out.println(person); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // Person 클래스 정의 - 직렬 class Person implements Serializable { String name; int age; String jumin; public Person(String name, int age, String jumin) { super(); this.name = name; this.age = age; this.jumin = jumin; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", jumin=" + jumin + "]"; } } |
- 전체코드
======== Ex7.java
- readme.txt 폴더에 넣기
import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class Ex7 { public static void main(String[] args) { /* p.598 * 파일 입출력(File IO) * - 바이너리 파일(Binary File) - 이미지 파일 등(이진데이터로 구성됨) * => byte 단위로 처리 필요(FileInputStream, FileOutputStream 클래스 사용) * - 텍스트 파일(Text File) : 일반 텍스트 문서 파일 * => char 단위로 처리 필요(FileReader, FileWriter 클래스 사용) * => BufferedReader, PrintWriter 등 사용 */ // File 객체 생성(지정된 경로와 파일명을 사용하여 File 객체 생성) // => 단, 실제 파일이 생성되는 것은 아니다! (객체가 만들어 지는 것) // File f = new File("D:\\temp\\readme.txt"); // 폴더명+파일명 결합하거나 File f = new File("D:\\temp", "readme.txt"); // 폴더명, 파일명 지정 가능 BufferedReader buffer = null; try { // FileReader 객체를 사용하여 지정된 File 객체의 파일 읽어오기 FileReader reader = new FileReader(f); // BufferedReader 객체를 생성하여 FileReader 객체 연결하기 buffer = new BufferedReader(reader); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { buffer.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
- 이렇게 써도 되지만 try ~ resources로 써보자
- try(FileReader reader = new FileReader(f); BufferedReader buffer = new BufferedReader(reader))
- 이렇게 사용 가능! (; 세미콜론만 있으면 여러개 가능하다)
try { // FileReader 객체를 사용하여 지정된 File 객체의 파일 읽어오기 // FileReader reader = new FileReader(f); // BufferedReader 객체를 생성하여 FileReader 객체 연결하기 // buffer = new BufferedReader(reader); // 위의 두 문장을 하나로 결합 buffer = new BufferedReader(new FileReader(f)); // BufferedReader 객체로부터 1개 라인을 String 타입으로 읽어오기 // => readLine() 메서드 사용 String str = buffer.readLine(); while(str != null) { System.out.println(str); str = buffer.readLine(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { buffer.close(); } catch (IOException e) { e.printStackTrace(); } } |
- 파일 읽어옴(따로 변환할 필요가 없다!)
import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; public class Ex8 { public static void main(String[] args) { System.out.println("출력할 데이터를 입력하세요."); // ---------- 입력받은 텍스트를 지정된 텍스트 파일에 출력 ----------- File f = new File("D:\\temp", "output.txt"); // 출력할 파일 지정 BufferedReader buffer = null; PrintWriter out = null; try { // BufferedReader 객체를 사용하여 키보드로부터 텍스트 입력받기 buffer = new BufferedReader(new InputStreamReader(System.in)); // FileWriter 객체를 사용하여 출력할 파일 객체 연결 FileWriter writer = new FileWriter(f); // PrintWriter 객체를 사용하여 FileWriter 객체 연결 out = new PrintWriter(writer); // 입력받은 텍스트 한 줄을 PrintWriter 객체의 print() 메서드로 출력 out.print(buffer.readLine()); } catch (IOException e) { e.printStackTrace(); } finally { try { buffer.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
======== Test8.java
import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; public class Test8 { public static void main(String[] args) { // ------------ 입력받은 텍스트를 지정된 텍스트 파일에 출력 --------------- // => 단, 여러 줄을 입력받아서 출력하도록 작성(종료 시 Ctrl + Z = null 입력) System.out.println("출력할 데이터를 입력하세요. (종료 : Ctrl + Z)"); File f = new File("D:\\temp", "output.txt"); // 출력할 파일 지정 BufferedReader buffer = null; PrintWriter out = null; try { // BufferedReader 객체를 사용하여 키보드로부터 텍스트 입력받기 buffer = new BufferedReader(new InputStreamReader(System.in)); // FileWriter 객체를 사용하여 출력할 파일 객체 연결 FileWriter writer = new FileWriter(f); // PrintWriter 객체를 사용하여 FileWriter 객체 연결 out = new PrintWriter(writer); // 입력받은 텍스트 여러 줄을 PrintWriter 객체의 print() 메서드로 출력 // => Ctrl + Z 가 입력되면 null 값이 전달되며, null 전달 시 종료 String str = buffer.readLine(); // 한 줄 읽어오기 while(str != null) { // 읽어온 문자열이 null(Ctrl + Z) 인지 판별 out.print(str + "\n"); // 줄바꿈 필요 str = buffer.readLine(); // 다음 줄 읽어오기 } } catch (IOException e) { e.printStackTrace(); } finally { try { // 입력스트림, 출력스트림을 별개로 반환(close()) buffer.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
- out.print(str + "\n"); // 줄바꿈 필요
- out.println(str); // 줄바꿈 필요 없음!
728x90
'Dev.Program > Java & Spring' 카테고리의 다른 글
[Spring] - (1)설치 및 설정하기 (0) | 2022.10.09 |
---|---|
InetAddress 클래스 (0) | 2022.10.07 |
MVC2 - (5) (0) | 2022.10.07 |
MVC2 - (4) (0) | 2022.10.07 |
MVC2 - (3) (0) | 2022.10.07 |