IT/JAVA (17.12.18~)

21일 JAVA(21)

만두토끼 2018. 1. 23. 16:08

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) {}

}


}


}