Java Io기반 입출력 및 네트웤 #2
file 클래스
파일 시스템의 파일을 표현하는 클래스
파일 객체 생성, 파일 똔느 디렉토리 존재 유무 확인, 파일 및 디렉토리 생성 및 삭제
예시.
import java.io.File; import java.net.URI; import java.text.SimpleDateFormat; import java.util.Date;
public class AFileExample {
public static void main(String[] args) throws Exception {
File dir = new File("C:/Temp/Dir");
File file1 = new File("C:/Temp/file1.txt");
File file2 = new File("C:/Temp/file2.txt");
File file3 = new File(new URI("file:///C:/Temp/file3.txt"));
if(dir.exists() == false) {dir.mkdir(); }
if(file1.exists() == false) {file1.createNewFile();}
if(file2.exists() == false) {file2.createNewFile();}
if(file3.exists() == false) {file3.createNewFile();}
File temp = new File("C:/Temp");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd a HH:mm");
File[] contents = temp.listFiles();
System.out.println("날짜 시간 형태 크기 이름");
for(File file : contents) {
System.out.print(sdf.format(new Date(file.lastModified())));
if(file.isDirectory()) {
System.out.print("\t<DIR>\t\t\t" + file.getName());
}else {
System.out.print("\t\t\t"+ file.length() + "\t" + file.getName());
}
System.out.println();
}
}
}
flieinputstream = 파일로부터 바이트 단위로 읽어 들일때 사용
객체 생성방법 = fileinputstream 객체가 생성될 때 파일과 직접 연결, 만약 파일이 존재하지 않으면
FileNoutFoundException발생 try-catch문으로 예외 처리
FileOutputStream 클래스는 바이트 단위로 데이터를 파일에 저장할 떄 사용하는 바이트 기반 출력 스트림이다
모든 종루의 데이터를 파일로 저장할수 있다 주의점은 이미 파일이 존재할경우 데이터를 출력하면
파일을 덮어 쓰게 되므로 기존의 파일내용은 사라진다. 역시 동일하게 파일을 저장할때도 계속 반복해서
끝까지 저장해주기위해 -1을 사용한다
예시 File Input Stream.
import java.io.FileInputStream;
public class AFileInputStream {
// 읽기.
public static void main(String[] args) {
try {
FileInputStream FIS = new FileInputStream("C:\\java.jae\\add\\src\\O028\\AFileInputStream.java");
int data;
while( (data = FIS.read() ) != -1) { // 읽어주기위해 반복실행 -1이 나올때까지 반복실행하기 위해 부정문을 사용
System.out.write(data);
}
FIS.close(); // 모두 읽은후 닫는다.
}catch(Exception e) {
e.printStackTrace();
}
}
}
예시. File Output Stream.
import java.io.FileInputStream; import java.io.FileOutputStream;
public class AFileOutputStreamExample {
public static void main(String[] args) throws Exception {
String OFileName = "C:\\java.jae\\add\\src\\O028\\LG.jpg"; // 여기 경로에 있는 파일을
String TFileName = "C:\\Temp\\LG.jpg"; // 여기경로에다
FileInputStream fis = new FileInputStream(OFileName); // 파일을 읽기위한 파일 인풋스트림
FileOutputStream fos = new FileOutputStream(TFileName); // 파일을 쓰기위한 파일 아웃풋스트림 // 요까지 딱 만들순있지만 파일은 손상된다. 내용물을 넣어야한다.
// 내용물을 넣기위한 반복.
int read;
byte[] reads = new byte[100]; // 한번에 100바이트를 읽어 reads에 저장하고
while( (read = fis.read(reads)) != -1) { // read가 -1이 아닐경우 fis의 인풋스트림으로 reads를 읽어 read에 저장한다.
fos.write(reads, 0, read); // reads에 0번째 인덱스부터 read의 배열의 크기만큼 저장한다.
}
//파일닫기
fos.flush();
fos.close();
fis.close();
System.out.println("복사 완류");
}
}
FileReader 클래스는 텍스트 파일을 프로그램으로 읽어들일 때 사용하는 문자 기반 스트림이다
문자로 읽기때문에 그림, 오디오, 비디오 등의 파일은 읽을수 없다.
만일 파일이 없을경우 오류가 발생하는데 FineNotFoundException을 발생 시키기에 try-catch문으로
예외처리를 한다
FileinputStream과 동일하게 -1이 나올때까지 읽어줄수있게 while를 사용한다.
문자를 char배열에 저장하기 위해 read(char[] cbuf)또는 read(char[] cbuf, int off, int len)을 사용한다.
예시 File Reader.
import java.io.FileReader;
public class AFileReaderExample {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("C:\\java.jae\\add\\src\\O028\\AFileReaderExample.java");
int readchar;
char[] cbuf = new char[100];
while( (readchar=fr.read(cbuf)) != -1) {
String data = new String(cbuf, 0, readchar);
System.out.print(data);
}
fr.close();
}
}
예시 File Writer
import java.io.File; import java.io.FileWriter;
import java.io.IOException;
public class AFileWriterExample {
public static void main(String[] args) throws Exception {
File f = new File("C:/Temp/file.txt");
FileWriter fw = new FileWriter(f, true);
fw.write("안녕 클레오파트라"+"\r\n");
fw.write("안녕 클레오파트라!"+"\r\n");
fw.write("안녕 클레오파트라!!"+"\r\n");
fw.flush();
fw.close();
System.out.println("저장");
}
}
보조 스트림은
다른 스트림과 연결되어 여러 가지 편리한 기능을 제공해주는 스트림이다 보조 스트림을 필터 스트림이라고도
한다 이는 보조 스트림의 일부가 FilterInputStream, FilterOutputStream의 하위 클래스이니까
보조스트림은 자체적으로 입출력을 할수없어서 소스와 연결되는 inputstream, fileinputstream, reader, filereader 출력 소스와 바로연결되는
outputstream fileoutputstream writer, filewriter등에 연결해서 입출력을 수행한다
보조 스트림은 문자변환 입출력 성능향상 기본데이터 타입 입출력 객체 입출력등 기능을 제공한단다
보조스트림 변수 = new 보조스트림(연결하려는스트림)을 작성해서 쓸수잇다
예시론 inputstreamreader이 보조스트림인데
inputstream is = system.in;주스트림이면
연결받으려면 inputstreamreader iss = new inputstreamreader(is); 이렇게 쓴단다
성능향상보조스트림은 BufferedReader이니 BufferedReader br = new BufferedReader(iss); 이렇게한단다
문자 변환 보조스트림 소스 스트림이 바이트 기반 스트림 이면서 입출력 데이터가 문자라면
Reader과 Writer로 변환해서 사용하는 것을 고려해야한대요 이유는 Reader과 Writer은 문자 단위로 입출력
하기때문에 바이트 기반 스트림보다는 편리하고, 문자셋의 종류를 지정할수 있어 다양한 문자를 입출력할수있다
InputStreamReader은 바이트 입력 스트림에 연결되어 문자 입력 스트림인 Reader로 변환시키는 보조 스트림이다
OutputStreamWriter은 바이트 출력 스트림에 연결되어 문자 출력 스트림인 Writer로 변환시켜주는 보조 스트림이다
예를 들어 파일 출력을 위한 FileOutputStream을 Writer타입으로 변환 할수있다
FileOutputStream fos = new FileOutputStream("파일주소");
Writer writer = new OutputStream(fos);
성능 향상 보조 스트림
프로그램의 실행 성능은 입출력이 가장 늦은 장치를 따라간다 cpu와 메모리가 아무리 좋아도
하드 디스크의 입출력이 늦어지면 프로그램의 실행 성능은 하드 디스크의 처리 속도에 맞춰진다
네트워크로 데이터를 전송할 때도 마찬가진데 느린 네트워크 환경이라면 컴퓨터 사양이 아무리 좋아도 메신저와
게임의 속도는 느릴 수 밖에 없다. 완전하게 해결책은 없지만 프로그램 입출력 소스와 직접 작업하지 않고 중간에
메모리 버퍼(buffer)이랑 같이 작업함으로 실행 성능을 향상 시킬순 있다
BufferedInputStream이랑 BufferedReader
BufferedInputStream은 바이트 입력스트림에 연결되어 버퍼를 제공해주는 보조 스트림이고
BufferedReader은 문자 입력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이다
BufferedInputStream이랑 BufferedReader는 입력 소스로부터 자신의 내부 버퍼 크기만큼
데이터를 미리 읽고 버퍼에 저장한다
예시론
BufferedInputStream bis = new BufferedInputStream(바이트입력스트림);
BufferedReader br = new BufferedReader(문자입력스트림);
BufferdReader는readLine()메소드를 추가적으로 더 갖구있는데 요 메소드를 이용하면
(\r)(\n)으로 구분된 행단위의 문자열을 한번에 읽을수 있다
예시론 Enter키를 입력하기전까지 콘솔에서입력한 모든 문자열을 얻어보자
Reader reader = new InputStreamReader(System.in);
BufferdReader br = new BufferdReader(reader);
String inputStr = br.readLine();
BufferdOutputSteam랑 BufferdWriter
BufferdOutputSteam은 바이트 출력 스트림에 여녁되어 버퍼를 제공해주는 보조 스트림이고
BufferdWriter은 문자 출력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이다
BufferdOutputSteam랑 BufferdWriter는 프로그램에서 전송한 데이터를 내부 버퍼에 쌓아두고
버퍼가 꽉 차면 버퍼의 모든 데이터를 한번에 보낸다 프로그램 입장에선
직접 데이터를 보내는게 아니라 메모리 버퍼로 데이터를 고속 전송하기 때문에 실행 성능이 향상
되는 효과가 있다
BufferdOutputSteam랑 BufferdWriter들은 생성자의 매개값으로 준 출력 스트림과 연결되어 내부에
8192라는 사이즈를 갖게 된다 문자를 최대 8192만큼 저장할수있다
import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader;
public class BInputStreamReaderExample {
// 한글 문자를 입력받아 출력한다. 보조 스트림
public static void main(String[] args) throws Exception{
InputStream is = System.in;
InputStreamReader isis = new InputStreamReader(is);
int readchar;
char[] cbuf = new char[100];
while( (readchar=isis.read(cbuf)) != -1) {
String data = new String(cbuf, 0, readchar);
System.out.print(data);
}
isis.close();
}
}
import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer;
public class BOutputStreamWriterExample {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("");
Writer writer = new OutputStreamWriter(fos);
String data = "안녕! 클레오 파트라!";
writer.write(data);
writer.flush();
writer.close();
System.out.print("끄읏");
}
}
import java.io.BufferedInputStream; import java.io.FileInputStream;
public class CBufferedInputStreamExample {
public static void main(String[] args) throws Exception {
long start = 0;
long end = 0;
//자아 buffered사용하고 사진을 읽어올때ㅜ
FileInputStream fis = new FileInputStream("C:\\java.jae\\add\\src\\O028\\LG.jpg");
BufferedInputStream bis = new BufferedInputStream(fis);
start = System.currentTimeMillis();
while(bis.read() != -1) {}
end = System.currentTimeMillis();
System.out.println("결과는~" + (end - start) + "ms");
bis.close();
fis.close();
}
}
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream;
public class CBufferedOutputStreamExample {
public static void main(String[] args) throws Exception {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos= null;
int data = -1;
long start = 0;
long end = 0;
fis = new FileInputStream("C:\\java.jae\\add\\src\\O028\\LG.jpg");
bis = new BufferedInputStream(fis);
fos = new FileOutputStream("C:\\Temp\\LG1.jpg");
start = System.currentTimeMillis();
while ( (data = bis.read()) != -1) {
fos.write(data);
}
fos.flush();
end = System.currentTimeMillis();
fos.close(); bis.close(); fis.close();
System.out.println("Buffered사용안할때 " + (end-start) + "ms");
fis = new FileInputStream("C:\\java.jae\\add\\src\\O028\\LG.jpg");
bis = new BufferedInputStream(fis);
fos = new FileOutputStream("C:\\Temp\\LG2.jpg");
bos = new BufferedOutputStream(fos);
start = System.currentTimeMillis();
while( (data = bis.read()) != -1) {
bos.write(data);
}
bos.flush();
end = System.currentTimeMillis();
bos.close(); fos.close(); bis.close(); fis.close();
System.out.println("Buffered사용했을때~" + (end-start) + "ms");
}
}
import java.io.Reader; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader;
public class CbufferedReaderExample {
public static void main(String[] args) throws Exception{
InputStream is = System.in;
Reader reader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(reader);
System.out.print("입력");
String a = br.readLine();
System.out.print("출력" + a );
}
}
기본타입 입출력 보조 스트림
바이트 타입으로 입출력하기 때문에 자바의 기본 데이터 타입단위로 입출력 할수 없다 그러나
DataUnputStream과 DataOutputStream보조 스트림을 연결하면 기본 데이터 타입으로 입출력이 가능
DataInputStream과 DataOutputStream객체를 생성하는 코드이다
다른 보조스트림과 마찬가지로 연결할 바이트 입출력 스트림을 생성자 매개값으로 준다
예시.
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream;
public class DataInputOutputStreamExample {
public static void main(String[] args) throws Exception{
//파일이 없으면 경로에 파일을만들고
FileOutputStream fos = new FileOutputStream("C:\\Temp\\abc.dat");
DataOutputStream dos = new DataOutputStream(fos);
//dat파일에 내용을 작성하고
dos.writeUTF("길동이");
dos.writeDouble(95.5);
dos.writeInt(1);
dos.writeUTF("또치");
dos.writeDouble(30.5);
dos.writeInt(2);
dos.close(); fos.close(); dos.flush();
//파일경로에 있는걸 읽어올껀데
FileInputStream fis = new FileInputStream("C:\\Temp\\abc.dat");
DataInputStream dis = new DataInputStream(fis);
// 내용을 출력시킬꺼다
for(int i=0; i<2; i++) {
String name = dis.readUTF();
double score = dis.readDouble();
int order = dis.readInt();
System.out.println(name+":"+ score+":"+ order);
}
dis.close(); fis.close();
}
}
프린터 보조 스트림
printStream과 printWriter은 프린터와 유사하게 출력하는 print(), println()메소드를
가지고 있는 보조 스트림이다. 지금까지 매우 빈번히 사용했던 콘솔 출력 스트림인 System.out이 바로
PrintStream타입이기 때문에 print(), println() 메소드를 사용할 수 있엇다. printStream은 바이트
출력 스트림과 연결되고,PrintWriter은 문자 출력 스트림과 연결된다. PrintStream과PrintWriter은 거의 같은
기능을 가지고 있다
PrintStream과 PrintWriter은 다른 보조 스트림과 마찬가지로 연결할 출력 스트림을 생성자의 매개 값으로
받는다.
예시1
import java.io.FileOutputStream; import java.io.PrintStream;
public class EPrintStream1Example {
public static void main(String[] args) throws Exception{
FileOutputStream fos = new FileOutputStream("C:/Temp/file.txt");
PrintStream ps = new PrintStream(fos);
ps.println("안녕 클레오 파트라");
ps.print("안녕 클레오 파트라");
ps.println("세상에서 제일가는");
ps.println("포테이토치입!!!!!!!!!!!");
ps.flush();
ps.close();
fos.close();
}
}
예시2
import java.util.Date;
import javax.xml.crypto.Data;
public class EPrintStreamExample {
public static void main(String[] args) {
System.out.printf("상품의 가격:%d원\n", 123);
System.out.printf("상품의 가격:%6d원\n", 123);
System.out.printf("상품의 가격:%-6d원\n", 123);
System.out.printf("상품의 가격:%06d원\n", 123);
System.out.printf("반지름이 %d인 원의 넓이:%10.2f\n",10, Math.PI*10*10);
System.out.printf("%6d | %-10s | %10s\n", 1, "길동이", "또치");
Date now = new Date();
System.out.printf("오늘은 %tY년 %tm월 %td일 입니다\n", now, now, now);
System.out.printf("오늘은 %1$tY년 %1tm월 %1$td일 입니다\n", now);
System.out.printf("현재 %1$tH시 %1$tM분 %1$tS초 입니다\n", now);
}
}
객체 입출력 보조 스트림
ObjectInputStream, ObjectOutputStream
자바는 객체를 입출력할 수 있는 두개의 보조 스트림인
ObjectInputStream, ObjectOutputStream를 제공한다
ObjectInputStream는 바이트 입력 스트림과 연결되어 객체를 “역직렬화” 하는 역할을하고
ObjectOutputStream은 바이트 출력 스트림과 연결되어 객체를 "직열화"하는역할을한다
ObjectInputStream, ObjectOutputStream은 다른 보조 스트림과 마찬가지로 연결할 바이트 입출력 스트림을 생성자의
매개값으로 받는다.
ObjectInputStream ois = new ObjectInputStream(바이트 입력스트림);
ObjectOutputStream oos = new ObjectOutputStream(바이트 출력스트림);
ObjectOutputStream으로 객체를 직렬화 하기 위해서는 writeObject() 메소드를 사용한다
반대로 ObjectInputStream의 readObject()메소드는 입력 스트림에서 읽은 바이트를 역직렬화
해서 객체로 생성한다 readObject()메소드의 리턴 타입은 Object 타입이기 때문에 객체 원래의 타입으로 변환해야한다.
output = oos.writeObject(객체);
input = 객체타입 변수 = (객체타입)ois.readObject();
예시
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class FObjectInputOutputStreamExample {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("C:/Temp/Object.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new Integer(100));
oos.writeObject(new Double(3.14));
oos.writeObject(new int[] {1,3,5,4});
oos.writeObject(new String("길동이"));
oos.flush(); oos.close(); fos.close();
FileInputStream fis = new FileInputStream("C:/Temp/Object.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
Integer obj1 = (Integer) ois.readObject();
Double obj2 = (Double) ois.readObject();
int[] obj3 = (int[]) ois.readObject();
String obj4 = (String) ois.readObject();
ois.close(); fis.close();
System.out.println(obj1);
System.out.println(obj2);
System.out.println(obj3[0] + "," + obj3[1] + "," + obj3[2] + "," + obj3[3]);
System.out.println(obj4);
}
}
Serializable 직렬화가 가능한 클래스
자바는 Serializable 인터페스르를 구현한 클래스만 직렬화할수 있도록 제한하고 있다. Serializable
인터페이스는 필드나 메소드가 없는 빈 인터페이스지만, 객체를 직렬화할 때 private 필드를 포함한
모든 필드를 바이트로 변환해도 좋다는 표시 역할을한다.
예시. public class XXX implements Serializable { }
객체를 직렬화하면 바이트로 변환되는 것은 필드들이고 생성자 및 메소드는 직렬화에 포함되지 않는다.
따라서 역직렬화할 때에는 필드의 값만 복원된다. 모든 필드가 직렬화 대상이 되는것은 아니다 필드 선언에
transient가 붙어 있는 경우에는 직렬화가 되지 않는다.
예시.
import java.io.Serializable;
public class GClassA implements Serializable {
int field1;
GClassB field2 = new GClassB();
static int field3;
transient int field4;
}
import java.io.Serializable;
public class GClassB implements Serializable {
int field1;
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class GSerializableExample {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("C:/Temp/Object.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
GClassA gc = new GClassA();
gc.field1 = 1;
gc.field2.field1 = 2;
gc.field3 = 3;
gc.field4 = 4;
oos.writeObject(gc);
oos.flush(); oos.close(); fos.close();
FileInputStream fis = new FileInputStream("C:/Temp/Object.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
GClassA gg =(GClassA) ois.readObject();
System.out.println("f1" + gg.field1);
System.out.println("f2" + gg.field2.field1);
System.out.println("f3" + gg.field3);
System.out.println("f4" + gg.field4);
}
}