* I/O (Input/Output) - 연결하고 읽고 쓰고, 끊는다.
- 표준입출력 : 키보드로 입력받고 모니터로 출력
- 파일입출력 : 파일의 것을 읽거나 파일로 출력
- network : 네트워크로 연결되어 있는 다른 컴퓨터와 교환
- 객체 직렬화 : 기본 데이터 (프리미티브 타입+문자열)
객체 데이터 : 읽고 쓰는 대상이 객체 일때
데이터를 저장 : 배열, ArrayList, Map, 파일, DB(select, update, delete, insert, trigger, tranjection, join)
- Stream : 데이터의 흐름(ex : 물이 흘러가는 통로)
- input : 데이터를 읽어 들이는 통
- output : 데이터를 흘려 보내는 통
* 항상 읽고 쓰는 것의 기준은 프로그램이다.
* java.io (성격에 따라서 세가지 구분법이 있다.)
1. Input/Output 계열로 구분
2. Node/Filter 계열로 구분
3. byte/char 계열로 구분
- Node : 연결이 목적인 Stream class
연결이 목적이 있는 입출력을 위한 기능만 제공
- Filter계열 : 기존의 stream(연결)에 읽고 쓰는 기능을 추가하는 class
기능 주기가 목적이므로 연결기능은 없다.
->Node로 연결하고 Filter로 기능추가.
* I/O
try{
1. 연결 - Node
기능추가 - Filter
2.I/O
}finally{
3.연결끊기 - Filter
}
--------------------------
- byte 계열 : 1byte단위 입출력처리 하는 Stream
binart code 입출력시 사용.
- charater 계열 : 2byte 단위 입출력 처리 Stream class
text 입출력시 사용
*I/O정리
--------------------------------------------------------------------------------------------
| Input계열 | Output계열
--------------------------------------------------------------------------------------------
| byte계열 | character계열 | byte계열 | character계열
--------------------------------------------------------------------------------------------
최상위class | InputStream | Reader | OutputStream | Writer
(추상) | | | |
--------------------------------------------------------------------------------------------
Node계열 | FileInputStream | FileReader | FileOuputStream | FileWriter
--------------------------------------------------------------------------------------------
Filter계열 | ObjectInputStream | BufferedReader | ObjectOutputStream | BufferedWriter
| DataInputStream | InputStreamReder | DataOutputStream | OuputStreamWriter
| | | | PrintWriter
--------------------------------------------------------------------------------------------
* Text를 I/o할때는 BufferedReader로 읽어 들이고 PrintWriter로 써준다.
* Node 계열의 생성자의 인수 : 연결대상.
Filter계열 생성자의 인수 : Stream class type
Reader/Writer
InputStream/OutputStream
InputStream
- 1byte - read() : int ->char(1byte)
- EOF : -1
byte b[] = new byte[100];
read(byte[]) : int //int는 읽은 byte의 수를 리턴해준다. EOF를 만나면 -1을 리턴해준다.
Reader
- read() : int ->char(2byte)
EOF : -1
char b[] = new char[100];
read(char[]) : int //int는 읽은 글자의 수를 리턴해준다. EOF를 만나면 -1을 리턴해준다.
ex :
int i =in.read();
while(i!=-1){
i=in.read();
}
//파일에 내용이 있을때까지 내용을 읽어 들어라.
* byte나 char 만 읽어 오므로 부호비트가 무조건 0이어서 -가 나올 수 없다. 그래서 EOF는 -1을 쓴다.
* close();연결끝는 메소드 , 이 메소드는 finally에 들어간다. (예외처리중)
* in.read()는 읽을게 없으면 읽을게 생길때 까지 기다린다.(멈춰있다가 읽을게 생기면 읽는다.) //I/O blocking.
* 출력
1. OutputStream
write(int) : void
인수로 받은 byte를 출력
* write(byte[]) //byte배열내의 data들을 한번에 출력, 만약 byte[10]이라면 10개의 글자를 읽어와서 한번에 출력한다.
write(byte[], int startIndex, int length) //byte배열내의 data중 startIndex에서 length만큼의 data출력.
2. Writer
write(int) : void
인수로 받은 char를 출력
* EOF는 -1을 읽어서 -1을 리턴하는 것이 아니라 EOF 파일의 끝을 만나면 -1을 리턴해주는 것이다.
write(char[])
write(char[], int idx, int length)
write(String)
* OutputStream 와 Writer의 공통 메소드
- close(); : 연결끊기
- flush() : 버퍼를 이용하는 stream의 버퍼내 Data들을 강제출력 처리.(ex : 화장실물내리기,)//close()전에 사용해서 버퍼에 있는 것을 다 출력시킨 후에 연결을 끊어주는 경우가 많다.
* 입출력 코딩 pattern
try{
1. 연결 - Node계열의 stream으로 연결한다.
Filter추가 - Filter계열의 Stream을 추가해 준다.
2. I/O 작업 read() - Filter로 읽고 쓴다.
write()
}finally{
3. 연결끊기 close() - Filter를 끊으면 Node도 같이 끊어진다.
}
Filter
* | Node로 연결
| |
ㅡㅡ|ㅡㅡㅡㅡㅡㅡ |ㅡㅡ
p/g ----|------------------ File
----|------------------
ㅡㅡ|ㅡㅡㅡㅡㅡㅡㅡㅡㅡ
| |
Filter
* Node로 통로를 만들고 Filter로 통로를 확장시키고 다 사용했다 하면 Filter로 연결을 끊어 주면 Node와 Filter다 연결이 끊어진다.
* File IO - 파일과 연결해서 I/O.
FileInputStream/ FileOutputStream
(binary code를 읽음.ex: 그림)
FileReader / FileWriter
(byte) (char)
(String file명)
ex :
FileWriter fw = new FileWriter("a.txt");
^
|
상대 경로 : 나를 기준으로(<-를 실행하고 있는 class파일을 기준으로 찾아 들어간다.) ..->부모 디렉토리, .->현재 디렉토리(폴더)
절대 경로 : C://a.txt 파일이 있는 전체주소를 다 써준다.
* 파일을 찾을 수 없으면 FileNotFoundException을 낸다.
-------------------------------------------------------------------------
*
project : day26
package : file.io
class : FileStreamTest
D:\Penguins.jpg
package file.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileStreamTest {
public static void main(String[] args) {
FileInputStream fi = null;
FileOutputStream fo = null;
try {
//1.연결
fi = new FileInputStream("d:\\Penguins.jpg");//파일이 있다면 그림파일과 연결이 끝난 상태가 된다.
//fo = new FileOutputStream("d:\\Penguins2.jpg"); //기존 데이터 붙여쓰기
fo = new FileOutputStream("d:\\Penguins.jpg",true); //파일 이어 붙이기
//2. I/O 작업(읽는 작업, 쓰는 작업)
int data = fi.read(); //1 바이트를 읽어옴
int count = 0;
long l1 = System.currentTimeMillis();
while(data!=-1){
fo.write(data);//출력
data = fi.read();//입력
count++;
}
long l2 = System.currentTimeMillis();
System.out.println("읽은 횟수 : "+count);
System.out.println("처리 시간 : "+(l2-l1)+"밀리초");
System.out.println("처리 시간 : "+(l2-l1)/1000+"초");
//3.정상적으로 끝났을 시에만 연결끊기
//fi.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//3. 연결끊기
if(fi!=null){//끝는 객체가 null이 아닌 경우에만 연결을 끊어라.(연결이 되어있는 경우만)
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fo!=null){
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
--------------------
===============================================================
*
project : day26
package : file.io
class : FileArrayStreamTest
package file.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileStreamArrayTest {
public static void main(String[] args) {
FileInputStream fi = null;
FileOutputStream fo = null;
try {
//1.연결
fi = new FileInputStream("d:\\Penguins.jpg");//파일이 있다면 그림파일과 연결이 끝난 상태가 된다.
fo = new FileOutputStream("d:\\Penguins2.jpg"); //기존 데이터 붙여쓰기
//fo = new FileOutputStream("d:\\Penguins2.jpg",true); //파일 이어 붙이기
//2. I/O 작업(읽는 작업, 쓰는 작업)
long l1 = System.currentTimeMillis();
int count = 0;
byte[] buff = new byte[10000];
int length = fi.read(buff);
while(length !=-1){
fo.write(buff);
length = fi.read(buff);
count++;
}
long l2 = System.currentTimeMillis();
System.out.println("반복횟 수 : "+count);
System.out.println("걸린 시간 : "+(l2-l1)+"밀리초");
System.out.println("걸린 시간 : "+(l2-l1)/1000+"초");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//3. 연결끊기
if(fi!=null){//끝는 객체가 null이 아닌 경우에만 연결을 끊어라.(연결이 되어있는 경우만)
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fo!=null){
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
-----------------------------
============================================================
file - 17byte
byte[] b = new byte[5];
int i = fi.read(b);
while(i!=-1){
fo.write(b);
i = fi.read(b);
}
배열의 크기가 5므로 2byte까지 넣고 3byte가 남아서 파일의 크기가 커진다.
그래서 파일의 크기를 같게 해주려면
file - 17byte
byte[] b = new byte[5];
int i = fi.read(b);
while(i!=-1){
fo.write(b,0,i);
i = fi.read(b);
}
를 해줘야한다.
위에 꺼 수정 예제
package file.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileStreamArrayTest {
public static void main(String[] args) {
FileInputStream fi = null;
FileOutputStream fo = null;
try {
//1.연결
fi = new FileInputStream("d:\\Penguins.jpg");//파일이 있다면 그림파일과 연결이 끝난 상태가 된다.
fo = new FileOutputStream("d:\\Penguins2.jpg"); //기존 데이터 붙여쓰기
//fo = new FileOutputStream("d:\\Penguins2.jpg",true); //파일 이어 붙이기
//2. I/O 작업(읽는 작업, 쓰는 작업)
long l1 = System.currentTimeMillis();
int count = 0;
byte[] buff = new byte[10000];
int length = fi.read(buff);
while(length !=-1){
fo.write(buff,0,length);
length = fi.read(buff);
count++;
}
long l2 = System.currentTimeMillis();
System.out.println("반복횟 수 : "+count);
System.out.println("걸린 시간 : "+(l2-l1)+"밀리초");
System.out.println("걸린 시간 : "+(l2-l1)/1000+"초");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//3. 연결끊기
if(fi!=null){//끝는 객체가 null이 아닌 경우에만 연결을 끊어라.(연결이 되어있는 경우만)
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fo!=null){
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
*
--------------------------
====================================================================
*
project : day26
package : file.io.character
class : FileReaderWriterTest
package file.io.character;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderWriterTest {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
//d:\news.txt 읽어서 d:\news2.txt로 쓰기 - char[]
try {
fr = new FileReader("d:\\news.txt");
fw = new FileWriter("d:\\news2.txt"); //연결할때마다 다 지우고 새로쓴다.
//fw = new FileWriter("d:\\news2.txt",true); //연결할때 이어쓴다.
char[] buff = new char[10000];
int count = 0;
int length = fr.read(buff);
while(length!=-1){
fw.write(buff,0,length); //읽은 글자 수만큼만 써라.
length = fr.read(buff);
count++;
}
System.out.println("반복횟수 : "+count);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fr!=null){ //파일연결이 실패하면 null이 들어간다. 그래서 null이 아닐시만 연결을 끊어줘야한다.
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
-----------------------------------
========================================================================
* 2012-3-29
- Input/Output
- Node계열(연결) / Filter계열(기능추가)
- byte계열(1byte) / character(2byte) - 언제쓰는지 질문
* a.txt
FileReader
FileWriter
* BufferedReader : Enter를 기준으로 읽어 들이는 기능.(라인단위로 받아옴)
* char(txt) byte(binary)
----------------------------------
I : Reader InputStream
O : Writer OutputStream
Node : 연결대상
Filter : InputStream
* 사용
try{
1. 연결 - Node
Filter추가
2. 읽고쓰기
}finally{
3. close();
}
-----------------------------------------------------------------------------
==============================================================================
*
project : day26
package : file.io.character.filter
class : BufferReaderWriterTest
package file.io.character.filter;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class BufferReaderWriterTest {
public static void main(String[] args) {
//Filter Stream을 이용한 입출력
//BufferedReader와 PrintWriter를 이용해 news.txt->new3.txt로 입/출력
FileReader fr = null;
FileWriter fw = null;
//Filter스트림
BufferedReader br = null; //버퍼를 이용, 라인단위로 읽는 기능
PrintWriter pw = null; //데이터 포멧에 맞게 출력, println(), print()기능
try {
//1-1연결
fr = new FileReader("d:\\news.txt");
fw = new FileWriter("d:\\news3.txt");
//1-2 filter 스트림 추가
br = new BufferedReader(fr);
//pw = new PrintWriter(fw);
pw = new PrintWriter(fw, true);//true : auto flush - println()하면 바로 출력된다. 버퍼를 이용하지 않고(쓸때마다 출력해야 하는 경우 사용한다.ex : 채팅프로그램)
//2 read(BufferedReader)/writer(PrintWriter)
String str = br.readLine();//엔터를 기준으로 읽어들임(엔터는 않읽는다.)//읽은것을 String으로 리턴
while(str!=null){ //EOF : null을 리턴
System.out.println(str);
pw.println(str); //버퍼에 출력할것을 담아둔다.(버퍼의 크기가 꽉차면 그 버퍼만큼은 출력해준다.)
str = br.readLine();
}
// pw.flush();//버퍼의 내용을 다 출력해준다.(버퍼에 있는 데이터를 최종 출력장소로 밀어내는 메소드
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//3 연결 끊기
if(br!=null){
try {
br.close(); //버퍼를 닫으면 연결이 끊어진다.
} catch (IOException e) {
e.printStackTrace();
}
}
if(pw!=null){
pw.close();
}
}
}
}
//파일에 enter가 들어가면 파일의 크기가 약간 커질수도 있다.