데이터 입출력 : IO(Input/Output)

2022. 10. 7. 16:37Dev.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