21일 JAVA(21)
1. Stream
1) OutputStream - ByteStream 들의 출력에 관련된 메소드 이름을 소유한 추상 클래스
void close(): 스트림 닫기
void flush(): 현재 버퍼에 남았있는 내용 모두 출력
void write(int r): r을 기록
void write(byte [] b): b의 모든 내용을 기록
void write(byte [] b, int offset, int length): b 배열에서 offset 부터 length 만큼 기록
2) InputStream - ByteStream 들의 입력에 관련된 메소드 이름을 소유한 추상 클래스
int available(): 스트림에서 읽을 수 있는 크기를 바이트 단위로 리턴
int read(): 하나의 바이트를 읽어서 정수로 리턴
못 읽으면 음수를 리턴
int read(byte [] b): b배열의 크기만큼을 읽어서 b에 저장하고 읽은 바이트 수를 리턴
데이터를 못 읽으면 0보다 작거나 같은 수를 리턴
int read(byte [] b, int offset, int length): b배열에 offset 부터 length 만큼을 읽어서 저장하고 읽은 개수를 리턴
데이터를 못 읽으면 0보다 작거나 같은 수를 리턴
3) .FileOutputStream
=>파일에 byte 단위로 기록하기 위한 스트림
생성자 - FileNotFoundException을 처리해야 합니다.
FileOutputStream(String name): 파일 경로에 파일이 없으면 생성하고 파일이 존재하면 기존 파일의 시작부분부터 기록합니다..
FileOutputStream(String name, boolean append): 파일 경로와 쓰기 모드를 설정하는데 두번째 매개변수가 true이면 파일이 있는 경우에 뒤에서 이어서 기록합니다.
FileOutputStream(File file): 매개변수로 파일의 경로를 문자열로 주지 않고 File 객체로 생성해서 대입합니다.
FileOutputStream(File file, boolean append)
실습) 파일생성 OR 파일이 존재하면 이어서 쓰기
package bytestream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileMain1 {
public static void main(String[] args) {
//반드시 close를 해야 하는 객체들을
//참조할 변수는 try 바깥에 선언합니다.
//try에 선언한 변수는 finally에서 사용할 수
//없기 때문입니다.
FileOutputStream fos = null;
try {
//파일 출력 객체 생성 - 존재하면 이어서 쓰기
fos = new FileOutputStream(
"sample.txt", true);
//파일에 기록
//fos.write(75);
fos.write("Oracle".getBytes());
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}finally {
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3) FileInputStream
생성자
FileInputStream(File file): File 객체를 대입
FileInputStream(String file): 파일의 경로를 문자열로 대입
실습) 파일 읽기(하나씩 읽기, 한꺼번에 읽기)
package bytestream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileMain2 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("sample.txt");
/*
//1바이트씩 읽기 - 한글은 문제 발생
//무한반복
while(true) {
//하나의 바이트 읽기
int r = fis.read();
//읽은 값이 없으면 종료
if(r<0) {
break;
}
System.out.println((char)r);
}
*/
/*
//한꺼번에 읽기
//파일의 크기가 크다면 읽는데 시간이 많이 걸립니다.
//읽을 수 있는 크기로 byte 배열을 생성
byte [] b = new byte[fis.available()];
//b 만큼 읽기
fis.read(b);
//바이트 배열을 문자열로 변환해서 출력
System.out.print(new String(b));
*/
while(true) {
//일정한 크기의 byte 배열 생성
//특별한 경우가 아니면 8의 배수
byte [] b = new byte[8];
//데이터 읽기
int r = fis.read(b);
//읽은 데이터가 없으면 종료
if(r <=0) {
break;
}
//읽은 데이터만 문자열로 변환해서 출력
System.out.println(new String(b,0,r));
}
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5) BufferedOutputStream -> PrintStream
=>이 2개의 스트림을 모아서 처리를 합니다.
=>출력을 할 때 마다 운영체제의 native method를 호출하지 않고 모아서 호출하기 때문에 호출횟수를 줄여서 출력을 효율적으로 할 수 있습니다.
- BufferedOutputStream
생성자
BufferedOutputStream(OutputStream out): 출력 스트림 객체를 대입해서 생성
BufferedOutputStream(OutputStream out, int size): 출력 스트림과 한 번에 기록할 버퍼의 크기를 설정해서 생성
- PrintStream
생성자
PrintStream(String fileName): 파일 경로를 가지고 생성
PrintStream(OutputStream out): OutputStream 객체를 가지고 생성
메소드
print(), printf(), println() 메소드를 제공
실습) PrintStream 을 사용
package bytestream;
import java.io.PrintStream;
public class FileMain3 {
public static void main(String[] args) {
//PrintStream을 이용해서 test.txt 파일에 기록하기
PrintStream ps = null;
try {
//출력 객체 생성
ps = new PrintStream("test.txt");
//데이터 출력
ps.println("안녕하세요 반갑습니다.");
//버퍼에 남은 내용을 전부 내보내기
ps.flush();
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}finally {
ps.close();
}
}
}
6) BufferedInputStream
=>버퍼를 이용해서 바이트 단위로 입력을 받는 스트림
생성자
BufferedInputStream(InputStream in): InputStream 객체를 이용해서 객체를 생성
BufferedInputStream(InputStream in, int size): InputStream 객체와 버퍼의 크기를 설정해서 객체를 생성
2. Chracter Stream
=>데이터를 문자 단위로 주고 받는 스트림
=>문자 단위로 주고 받을려면 인코딩 방식이 같아야 합니다.
1) 인코딩 방식
=>문자 데이터를 컴퓨터의 메모리에 저장하기 위해서 숫자로 변경하는 방식
- ASCII Code
=>영문자와 숫자를 표현하기 위한 방식으로 전세계 모든 곳에서 공통으로 사용
=>영문자나 숫자 1개를 8bit 로 표현(시험에서는 7bit)
=>'0' -> 48, 'A' -> 65, 'a' -> 97, NULL -> 0
- EUC-KR(MS949, CP949)
=>Microsoft가 한글을 표현하는 방법
=>Windows는 기본적으로 CP949 이고 IE(Internet Explorer) 예전버전이 사용
=>예전에 만들어진 웹 사이트의 인코딩이 이 방식입니다.
- UTF-8
=>Microsoft를 제외한 운영체제에서의 한글 표현 방법
=>IE를 제외한 모든 브라우저가 UTF-8 방식
=>최근에 만들어진 웹 사이트의 인코딩은 거의 이 방식입니다.
2) Writer
=>문자 단위로 기록하기 위한 메소드의 이름을 가진 추상클래스
=>메소드
void close(): 닫기
void flush(): 버퍼에 있는 모든 내용을 출력
void write(String str): 문자열 전체를 기록
void write(String str, int off, int len): 문자열에서 off 부터 len 만큼 기록
3) FileWriter
FileWriter(File file): File 객체로 만들기
FileWriter(File file, boolean append): File 객체와 추가모드를 설정해서 객체 만들기
FileWriter(String filepath): 파일 경로를 가지고 만들기
FileWriter(String filepath, boolean append): 파일 경로와 추가모드를 설정해서 객체 만들기
4) BufferedWriter -> PrintWriter
- 생성자
PrintWriter(String fileName): 파일 경로를 가지고 생성
PrintWriter(File file): File 객체를 가지고 생성
PrintWriter(OutputStream out): Network를 통해서 얻어온 OutputStream 객체를 가지고 만들 때 주로 사용
PrintWriter(Writer out): FileWriter 와 같은 객체를 이용해서 생성
- 메소드
기록하는 메소드로 print, printf, println 이 추가되어 있습니다.
5) Reader
=>문자 단위로 데이터를 읽기 위한 메소드를 소유한 추상 클래스
=>메소드
void close(): 닫기
int read(): 한 글자를 읽어서 리턴
글자를 못 읽으면 음수를 리턴
int read(char[] cbuf): cbuf의 크기만큼 읽어서 cbuf에 저장하고 읽은 개수를 리턴하는데 못 읽으면 0보다 작거나 같은 수를 리턴
int read(char[] cbuf, int off, int len): cbuf 배열에 off 부터 len 만큼 읽어서 cbuf에 저장하고 읽은 개수를 리턴하는데 못 읽으면 0보다 작거나 같은 수를 리턴
6) FileReader
=>생성자
FileReader(File file): File 객체를 가지고 만들기
FileReader(String fileName): 파일의 경로를 문자열로 대입해서 만들기
7) BufferedReader
=>생성자
BufferedReader(Reader in): Reader 객체를 가지고 만들기
BufferedReader(Reader in, int cz): Reader 객체와 버퍼의 크기를 설정해서 만들기
=>메소드
String readLine(): 줄 단위로 읽어서 리턴하는데 읽은 게 없으면 null을 리턴
실습) 문자열 단위로 데이터 읽기, BufferedReader를 사용
package characterstream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileMain1 {
public static void main(String[] args) {
//문자열 단위로 데이터를 읽기 위한 변수
BufferedReader br = null;
try {
br = new BufferedReader(
new FileReader("\\\\192.168.0.200\\data\\Java\\java\\0102.txt"));
//줄 단위로 읽어서 출력하기
while(true) {
//한 줄 읽기
String line = br.readLine();
//못 읽었으면 중단
if(line == null) {
break;
}
//출력
System.out.println(line);
}
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}finally {
if(br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3. 객체 단위 저장 - Serializable 인터페이스
=>파일이나 네트워크에서 데이터를 전송하거나 읽을 때 객체 단위로 읽고 쓸 수가 있는데 객체 단위로 저장을 하거나 읽을려고 할 때는 객체의 클래스가 Serializable 인터페이스를 implements 했을 때 만 가능합니다.
=>이렇게 데이터를 전송하면 클래스 이름과 함께 데이터가 저장되서 클래스가 있는 경우에만 올바르게 읽을 수 있게 됩니다.
=>이 경우에 사용하는 Stream은 ObjectInputStream 과 ObjectOutputStream 입니다.
1) 동일한 레벨을 가진(비교 가능한) 여러 개의 데이터를 하나로 묶는 방법
- 배열 - 개수가 고정일 때
- ArrayList - 개수가 변할 때 그리고 데이터 삽입 및 삭제 가 중간에서 일어나지 않는 경우
- LinkedList - 개수가 변할 때 그리고 검색보다는 데이터 삽입 및 삭제가 중간에서 빈번히 발생할 때
- Set - 데이터를 중복없이 저장하고자 하는 경우
2) 여러 개의 항목(비교 불 가능한)을 하나로 묶는 방법
- DTO 클래스: 별도의 클래스를 생성해서 저장
- Map을 이용해서 바로 객체를 생성해서 저장
3) 이름과 나이를 묶어서 저장할 수 있는 클래스를 생성
->저장하고자 하는 속성을 private 변수로 선언
-> 변수의 접근자 메소드 생성
-> toString 메소드 재정의
-> 객체 단위로 저장하고자 하면 Serializable 인터페이스를 implements
package serializable;
import java.io.Serializable;
//Data 클래스의 객체는 파일에 바로 저장할 수 있고 네트워크를 통해서
//전송이 가능해 집니다. -> Serializable를 구현했기 때문에
public class Data implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Data [name=" + name + ", age=" + age + "]";
}
}
4) ObjectOutputStream
=>객체 단위로 전송하기 위한 스트림
- 생성자
ObjectOutputStream(OutputStream out): OutputStream 객체를 만들어서 대입해야 합니다.
- 메소드
void writeObject(Serializable obj): obj를 기록하는데 반드시 Serializable 인터페이스를 implements 한 객체이어야 합니다.
package serializable;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializableMain {
public static void main(String[] args) {
//Data 클래스의 객체 만들기
Data data = new Data();
data.setName("태연");
data.setAge(30);
//파일에 객체 단위로 기록하기 위한 변수 선언
ObjectOutputStream oos = null;
try {
//파일에 기록할 수 있는 객체 생성
oos = new ObjectOutputStream(
new FileOutputStream("oop.dat"));
//데이터 기록
oos.writeObject(data);
}catch(Exception e) {
//예외가 발생했을 때 메시지 출력
System.out.println("예외:" + e.getMessage());
//예외가 발생한 지점을 찾기 위해서 역추적
e.printStackTrace();
}finally {
try {
if(oos != null) {
oos.close();
}
}catch(Exception e) {}
}
}
}
5) ObjectInputStream
=>파일이나 네트워크에서 데이터를 객체 단위로 읽어 오기 위한 스트림
- 생성자
ObjectInputStream(InputStream is)
- 메소드
Object readObject(): 객체를 읽어옵니다.
=>return type이 Object 이면 원래의 자료형으로 형변환해서 사용해야 합니다.
package serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializableMain1 {
public static void main(String[] args) {
ObjectInputStream ois = null;
try {
//객체 단위로 읽기 위한 객체 생성
ois = new ObjectInputStream(
new FileInputStream("oop.dat"));
//하나의 데이터를 읽어서 data에 저장
//이 때 반드시 저장한 클래스 타입으로 형변환해야 합니다.
Data data = (Data)ois.readObject();
System.out.println(data);
}catch(Exception e) {
//예외가 발생했을 때 메시지 출력
System.out.println("예외:" + e.getMessage());
//예외가 발생한 지점을 찾기 위해서 역추적
e.printStackTrace();
}finally {
try {
if(ois != null) {
ois.close();
}
}catch(Exception e) {}
}
}
}