본문 바로가기

아옳옳의 코딩공부/아옳옳 자바코딩공부

2021-05-10자바공부(파일과 I/O 스트림)

반응형

여기서 스트림이란 흐름 이라고 생각하면 된다 입력의 흐름 출력의 흐름 이라고 생각하면 된다 . 

 

위에서 말했듯이 스트림도 인스턴스생성을 통해서 형성된다 했는데 출력과 입력 각각 인스턴스를 해야 사용이 가능하다 

 

자바의 스트림

입력 스트림: 입력장치로부터 자바 프로그램으로 데이터를 전달하는 소프트웨어 모듈

출력 스트림: 자바 프로그램에서 출력장치로 데이터를 보내는 소프트웨어 모듈 

입출력 스트림기본 단위 : 바이트 

단방향 스트림 

 

파일 기반의 입출력 스트림

입력스트림 

한글과 영어는 2byte 

 

출력스트림 

주요 메소드도 보면 비슷하여 이해나 사용하는데 큰 어려움은 없을것이다. 

 

이렇게 파일도 복사를 할 수있는데 이렇게하게되면 1바이트씩 얻어고 1바트씩 작업을 하기 때문에 작업 시간이 상당히 길어지는게 단점이다. 

이렇게 바이트 단위로 읽어 오고 내보내지만 이것은 4바이트 int형하나로 변경 하려면 어떻게 해야될까? 

1단계 : 파일로부터 1바이트 데이터 4개를 읽어 온다 

2단계 읽어들인 1바이트 데이터 4개를 하나의 int형으로 조합한다 ( 필터 스트림 역활 ) 

 

 

실습으로 확인 해보자 

public class DataFilterOutputStream {

	public static void main(String[] args) {

	try (DataOutputStream out = 
	new DataOutputStream(new FileOutputStream("data.txt"))) {

			out.writeInt(360);
			out.writeDouble(3.14);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

일단 출력을 해주기이전에 DataOutputStream에 필터를 달아주면서 data라는 txt파일을 만들어주었고 거기에 int 형 340과 double형 3.14를 넣어주었다 

public class DataFileterInputStream {

	public static void main(String[] args){
	
		try(DataInputStream in = 
		new DataInputStream(new FileInputStream("data.txt"))){
			int num = in.readInt();
			double num2 = in.readDouble();
			System.out.println(num +":"+ num2 );
		}catch(IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

그리고 나서 DataInputStream에 필터를 달아주고 읽어 와주면서 기본 자료형에 담은 것들을 출력 해보았다 

이렇게 잘 불러와주는것을 볼수있다. 

자 계속해서 다음 그림을 보자 

그림을 보고 위쪽처럼 바구니에 하나만 담아서 하는 사람을 아무도 없을 것이다. 이처럼 데이터도 한번에 받아서 처리는게 속도에도 더욱 빠르기 때문에 이런 부분들을 도와주는 필터스트림도 있다. 

아까 코드로 예제 풀어 본것에서 몇가지만 추가해주면 된다 . 

이런식으로 중간에 추가만 해주게 되면 된다. 

그럼 시간이 얼마나 차이가 나는지 한번 확인 해보자~ 

 

메인

	public static void main(String[] args) throws Exception{

		OutputStream out1 = new FileOutputStream("data1.txt");
		DataOutputStream dataOut = new DataOutputStream(out1);
		Data_Perormance.performance(dataOut);
		dataOut.close();
		
		OutputStream out2 = new FileOutputStream("data2.txt");
		DataOutputStream dataOut2 = new DataOutputStream(out2);
		BufferedOutputStream A = new BufferedOutputStream(dataOut2,(1024*10)); 
		Data_Perormance.performance(dataOut2);
		dataOut.close();
		
	}
}
public class Data_Perormance {

	public static void performance(DataOutputStream dataOut) throws Exception{
		
		long startTime = System.currentTimeMillis();
		
		for(int i=0;i<1000; i++) {
			for(int j=0;j<1000;j++) {
				dataOut.writeDouble(12.345);
			}
		}
		dataOut.flush();
		
		long endTime = System.currentTimeMillis();
		System.out.print("경과시간:" +(startTime-endTime));
		
	}
}

이렇게 해서 해보면 크게 차이는 없는것처럼 보이지만 큰 파일들 작업할때는 많이 차이가 날것이다. 

 

작성할때 순서는 이렇게 작성해주면 된다 . 

 

문자스트림 

메소드가 크게 달라지는것이 없어 사용하기 불편함은 없다. 

 

문자 스트림을 활용한 예제 

public class check {

	public static void main(String[] args) {			
		try {
			Writer writ = new FileWriter("data.txt");
			for (int a = (int)'A';a<=(int)'Z';a++) {
			writ.write(a);
			}
			writ.close();						
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 

객체도 입출력으로 사용할수 있다. 하지만 잘 알아야하는 부분이 객체 자체가 이동되는것이 아닌 객체의 내용물만 가기 때문에 받는곳에도 같은 객체가 있어야 한다. 

예전에 intent 할때 배웠던 직렬화이다. 인텐트 참조 

그리고 마지막으로 직렬화에서 대상에서 제외 시킬수도 있다.  transient

 

오늘 배운 입출력을 총 동원하여 마지막으로 하나만 해보고 오늘은 마무리 하겠다. 

=====================A 클래스 ====================
public class ClassA implements Serializable{	
		int field1;
		ClassB field2 = new ClassB();
		static int field3;
		transient int field4;	
}

=====================B 클래스 ====================
public class ClassB implements Serializable {
	
	int field1;
	
}
=====================메인클래스 ====================
public static void main(String[] args) throws Exception {

		ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("D:/obj.txt"));
		ClassA classA = new ClassA();
		classA.field1 = 1;
		classA.field2.field1 = 2;
		classA.field3 = 3;
		classA.field4 = 4;
		os.writeUTF("안녕");
		os.writeObject(classA);

		os.flush();
		os.close();

		ObjectInputStream oi = new ObjectInputStream(new FileInputStream("D:/obj.txt"));
		System.out.println(oi.readUTF());
		ClassA instance = (ClassA) oi.readObject();
		System.out.println("field1 :" + instance.field1);
		System.out.println("field2 :" + instance.field2.field1);
		System.out.println("field3 :" + instance.field3);
		System.out.println("field4 :" + instance.field4);

	}

}

결과를 보면 transient시킨 부분은 0이라고 출력이 되는 것을 볼수있는데 . 정수는 0 문자는 null 로 찍힌다. 

반응형