보조 스트림
- 실제 읽고 쓰는 스트림이 아닌 보조 기능을 제공하는 스트림
- FilterInputStream과 FilterOutputStream이 보조 스트림의 상위 클래스들
- 생성자의 매개변수로 또 다른 스트림(기반 스트림이나 다른 보조 스트림)을 가짐
- Decorator Pattern으로 구현 됨(상속으로 하면 hierarchy(계층)가 복잡해지니 대신이거씀)
- 상위 클래스 생성자
생성자
protected FilterInputStream과(InputStream in) |
생성자의 매개변수로 InputStream을 받습니다. |
public FilterOutputStream(OutputStream out) |
생성자의 매개변수로 OutputStream을 받습니다. |
InputStreamReader와 OutputStreamWriter
- 바이트 단위로 읽거나 쓰는 자료를 문자로 변환해주는 보조 스트림
- FileInputStream으로 읽은 자료를 문자로 변환해주는 예
public class InputStreamReaderTest {
public static void main(String[] args) {
try(InputStreamReader isr = new InputStreamReader(new FileInputStream("reader.txt"))){
int i;
while( (i = isr.read()) != -1){ //보조 스트림으로 읽습니다.
System.out.print((char)i);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
BufferedInputStream과 BufferedOutputStream
- 약 8k의 배열이 제공되어 입출력이 빠르게 하는 기능이 제공되는 보조 스트림
- BufferedReader와 BufferedWriter는 문자용 입출력 보조 스트림
- BufferedInputStream과 BufferedOutputStream을 이용하여 파일 복사하는 예
public class BufferedStreamTest {
public static void main(String[] args) {
long millisecond = 0;
try(FileInputStream fis = new FileInputStream("a.zip");
FileOutputStream fos = new FileOutputStream("copy.zip");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos)){
millisecond = System.currentTimeMillis();
int i;
while( ( i = bis.read()) != -1){
bos.write(i);
}
millisecond = System.currentTimeMillis() - millisecond;
}catch(IOException e) {
e.printStackTrace();
}
System.out.println("파일 복사 하는 데 " + millisecond + " milliseconds 소요되었습니다.");
}
}
>>BufferedInputStream, BufferedOutputStream 안쓰면 한번에 한바이트씩 읽고쓰니 오래걸림
DataInputStream과 DataOutputStream
- 자료가 메모리에 저장된 상태 그대로 읽거나 쓰는 스트림
- DataInputStream 메서드
BufferedInputStream과 BufferedOutputStream
-
- 약 8k의 배열이 제공되어 입출력이 빠르게 하는 기능이 제공되는 보조 스트림
- BufferedReader와 BufferedWriter는 문자용 입출력 보조 스트림
- BufferedInputStream과 BufferedOutputStream을 이용하여 파일 복사하는 예
public class BufferedStreamTest {
public static void main(String[] args) {
long millisecond = 0;
try(FileInputStream fis = new FileInputStream("a.zip");
FileOutputStream fos = new FileOutputStream("copy.zip");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos)){
millisecond = System.currentTimeMillis();
int i;
while( ( i = bis.read()) != -1){
bos.write(i);
}
millisecond = System.currentTimeMillis() - millisecond;
}catch(IOException e) {
e.printStackTrace();
}
System.out.println("파일 복사 하는 데 " + millisecond + " milliseconds 소요되었습니다.");
Socket socket = new Socket();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
br.readLine(문자읽고~~);
}
}
DataInputStream과 DataOutputStream
-
- 자료가 메모리에 저장된 상태 그대로 읽거나 쓰는 스트림
- DataInputStream 메서드
public class DataStreamTest {
public static void main(String[] args) {
try(FileOutputStream fos = new FileOutputStream("data.txt");
DataOutputStream dos = new DataOutputStream(fos))
{
dos.writeByte(100); >>> byte로 썼으면
dos.writeChar('A');
dos.writeInt(10);
dos.writeFloat(3.14f);
dos.writeUTF("Test");
}catch(IOException e) {
e.printStackTrace();
}
try(FileInputStream fis = new FileInputStream("data.txt");
DataInputStream dis = new DataInputStream(fis))
{
System.out.println(dis.readByte()); >> byte로 읽어야 함
System.out.println(dis.readChar());
System.out.println(dis.readInt());
System.out.println(dis.readFloat());
System.out.println(dis.readUTF());
}catch (IOException e) {
e.printStackTrace();
}
}
}
serialization 이란?
- 인스턴스의 상태를 그대로 파일 저장하거나 네트웍으로 전송하고 (serialization) 이를 다시 복원(deserializatio) 하는 방식
- 자바에서는 보조 스트림을 활용하여 직렬화를 제공함
- ObjectInputStream과 ObjectOutputStream
ObjectInputStream(InputStream in) |
InputStream을 생성자의 매개변수로 받아 ObjectInputStream을 생성합니다. |
ObjectOutputStream(OutputStream out) |
OutputStream을 생성자의 매개변수로 받아 ObjectOutputStream을 생성합니다. |
Serializable 인터페이스
- 직렬화는 인스턴스의 내용이 외부로 유출되는 것이므로 프로그래머가 해당 객체에 대한 직렬화 의도를 표시해야 함
- 구현 코드가 없는 marker interface
- transient : 직렬화 하지 않으려는 멤버 변수에 사용함 (Socket등 직렬화 할 수 없는 객체)
class Person implements Serializable{
private static final long serialVersionUID = -1503252402544036183L;
String name;
transient String job; >> socket처럼 직렬화안되는 개체는 저렇게하면됨
public Person() {}
public Person(String name, String job) {
this.name = name;
this.job = job;
}
public String toString()
{
return name + "," + job;
}
}
public class SerializationTest {
public static void main(String[] args) throws ClassNotFoundException {
Person personAhn = new Person("이순신", "대표이사");
Person personKim = new Person("김유신", "상무이사");
try(FileOutputStream fos = new FileOutputStream("serial.out");
ObjectOutputStream oos = new ObjectOutputStream(fos)){
oos.writeObject(personAhn);
oos.writeObject(personKim);
}catch(IOException e) {
e.printStackTrace();
}
try(FileInputStream fis = new FileInputStream("serial.out");
ObjectInputStream ois = new ObjectInputStream(fis)){
Person p1 = (Person)ois.readObject();
Person p2 = (Person)ois.readObject();
System.out.println(p1);
System.out.println(p2);
}catch (IOException e) {
e.printStackTrace();
}
}
}
Externalizable 인터페이스
- writerExternal()과 readExternal()메서드를 구현해야 함
- 프로그래머가 직접 객체를 읽고 쓰는 코드를 구현 할 수 있음
class Person implements Externalizable{
String name;
String job;
public Person() {}
public Person(String name, String job) {
this.name = name;
this.job = job;
}
public String toString()
{
return name + "," + job;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name);
//out.writeUTF(job);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = in.readUTF();
//job = in.readUTF();
}
}
File 클래스
- 파일 개념을 추상화한 클래스
- 입출력 기능은 없고, 파일의 이름, 경로, 읽기 전용등의 속성을 알수 있음
- 이를 지원하는 여러 메서드들이 제공됨
public class FileTest {
public static void main(String[] args) throws IOException {
File file = new File("D:\\JAVA_LAB\\Chapter6\\newFile.txt");
// 파일은 없어도 디렉토리는 있어야 함
file.createNewFile(); // 이거 써야 파일생성함
System.out.println(file.isFile());
System.out.println(file.isDirectory());
System.out.println(file.getName());
System.out.println(file.getAbsolutePath());
System.out.println(file.getPath());
System.out.println(file.canRead());
System.out.println(file.canWrite());
file.delete();
}
}
RandomAccessFile 클래스
- 입출력 클래스 중 유일하게 파일에 대한 입력과 출력을 동시에 할 수 있는 클래스
- 파일 포인터가 있어서 읽고 쓰는 위치의 이동이 가능함
- 다양한 메서드가 제공됨
public class RandomAccessFileTest {
public static void main(String[] args) throws IOException {
RandomAccessFile rf = new RandomAccessFile("random.txt", "rw");
rf.writeInt(100);
System.out.println("파일 포인터 위치:" + rf.getFilePointer()); //int 4byte라 4
rf.writeDouble(3.14); // double : 8byte
System.out.println("파일 포인터 위치:" + rf.getFilePointer()); // 4+8 , 12
rf.writeUTF("안녕하세요"); // 한글은 3byte씩 15 + 끝에 null 2byte
System.out.println("파일 포인터 위치:" + rf.getFilePointer()); 12+17 =29
rf.seek(0); // 다시 맨앞으로 가라
System.out.println("파일 포인터 위치:" + rf.getFilePointer());
int i = rf.readInt();
double d = rf.readDouble();
String str = rf.readUTF();
System.out.println("파일 포인터 위치:" + rf.getFilePointer());
System.out.println(i);
System.out.println(d);
System.out.println(str);
}
}
=========
파일 포인터 위치 : 4
파일 포인터 위치: 12
파일 포인터 위치: 29
파일 포인터 위치:0
파일 포인터 위치:29
100
3.14
안녕하세요
댓글 영역