java.io 관련 이미지



java.io 패키지중 
1.DataInput 인터페이스(몇몇 input 인터페이스의 상위 인터페이스) http://xrath.com/javase/ko/6/docs/ko/api/index.html 

DateInputStream 필터 타입의 인풋 클래스의 경우..
1.추상 클래스인 InputStream 2.필터타입 클래스인 FilterInputStream(생성자가 protected라 거의 추상클래스)을 단계적으로 상속받고 
+ 3.DataInput 인터페이스, CloseAble 인터페이스까지 조립해서 만들어지는 필터타입의 인풋 클래스이다.
  
너무 편리해서 내가 제일 선호하는 ObjectInputStream 필터 타입의 인풋 클래스의 경우..(일반적인 직렬화,프로세스 통신에는
ObjectOutputStream이 좋다)
1.추상 클래스인 InputStream 을 상속받고 위와는 다르게 Filterxxx 는 받을 필요가 없고.. 대신에 
2.DataInput 인터페이스(primitive 인풋을 위해) + OjbectInput 인터페이스(DataInput을 확장해 객체,String,배열등의 인풋을 위해)
+ CloseAble 인터페이스(스트림등 리소스 닫기용) + ObjectStreamConstance 인터페이스(프리미티브를 조립해서 객체 타입을
정의하니까 조립 정보를 직렬화 Serializable (인/아웃풋시 복원을 위한 규칙) 를 지원하기 위한 표시랄까? 말을 해놓고도 애매하네..)
를 조립해서 만들어지는 필터타입의 인풋 클래스이다.

물론 실제 사용시에는 대상 스트림을 열수 있는 "노드 계열"의 인풋 클래스가 필요할테고, 일반적으로 목적이 파일 작업시라면.. 
a. 파일경로+파일이름, 덮어쓸지 여부를 매개변수로 File 객체 생성 (예외처리등 생략)
b. a를 매개변수로 노드계열의 FileInputStream 객체 생성
c. b를 매개변수로 필터계열의 ObjectInputStream 객체 생성
d. objectInputStream의 객체를 가지고 readObject() 를 사용하면 파일에 저장된 객체를 리턴해주고
e. 용건 끝났으니 FileInputStream 해제해서 리소스 풀어주고, 그담엔 ObjectInputStream 해제해서 리소스 풀어주고 (익셉션
   발생시 조심해야 하니까 속 편하게 finally{} 에서 해제) =>필터계열의 스트림 객체만 close() 해주면 된다! 
f. 저 위에서 살펴본 객체를 i/o하기 위한 수많은 고민들을 몰라도 a~e처럼 손쉽게 사용이 가능해서 행복할 따름이고..
(읽기,쓰기 작업시 몇몇 다르게 고려할게 있긴 했지만.. 논외 .. 아 추가적으로 내가 클래스를 정의하고 그것을 파일에 readObject, writeObject 하기 위해선 내 클래스에 implements Serializable하고 sid(클래스의 변경에 따른 버전 관리)인가를 받아야 했다. 꽤 오래돼서 기억이 가물하지만.. 내 클래스를 직렬화 하겠다고 정의하는것)

2.Serializable 인터페이스의 하위 인터페이스들의 면면을 보라! 

java.io 
인터페이스 Serializable

기존의 서브 인터페이스의 일람:
AdapterActivator , Attribute , Attribute , Attributes , BindingIterator , ClientRequestInfo 
ClientRequestInterceptor , Codec , CodecFactory ,Control , Current , Current , Current
 , CustomValue , DataInputStream , DataOutputStream , Descriptor , DHPrivateKey , 
DHPublicKey ,DocAttribute , DomainManager , DSAPrivateKey , DSAPublicKey , DynAny 
DynAnyFactory , DynArray , DynEnum , DynFixed , DynSequenceDynStruct , DynUnion
 , DynValue , DynValueBox , DynValueCommon , ECPrivateKey , ECPublicKey , 
ExtendedRequest ,ExtendedResponse , Externalizable , IdAssignmentPolicy , IDLEntity ,
 IDLType , IdUniquenessPolicy , ImplicitActivationPolicy , Interceptor ,IORInfo ,
IORInterceptor , IORInterceptor_3_0 , IRObject , Key , LifespanPolicy , Name , 
NamingContext , NamingContextExt ,NotificationFilter , ObjectReferenceFactory ,
 ObjectReferenceTemplate , ORBInitializer , ORBInitInfo , PBEKey , POA , POAManager ,
 Policy ,PolicyFactory , PrintJobAttribute , PrintRequestAttribute , PrintServiceAttribute ,
 PrivateKey , PublicKey , QueryExp , RelationType ,RemoteRef , RequestInfo , 
RequestProcessingPolicy , RSAMultiPrimePrivateCrtKey , RSAPrivateCrtKey , 
RSAPrivateKey , RSAPublicKey ,RunTime , SecretKey , ServantActivator , 
ServantLocator , ServantManager , ServantRetentionPolicy , ServerRef , 
ServerRequestInfo ,ServerRequestInterceptor , StreamableValue ,
 SupportedValuesAttribute , ThreadPolicy , UnsolicitedNotification , ValueBase , 
ValueExp

(etc) java.io.StreamTokenizer (한번 사용해볼 기회가 있을라나?)

 


(추가)NIO 패키지는 비동기 IO의 측면에서 굉장히 중요한 개념이다. 출판/구독패턴으로 문제를 해결했으며,
이벤트/콜백(개발자가 아닌, 프레임워크OR 라이브러이가 내 코드를 역제어 개념)에 대한 공부하길 잘했다.


(추가)이 개념이 SPING이란 프레임워크 프로그래밍, AJAX 프로그래밍, 자바스크립트의 이벤트 콜백을 활용
한 함수형 프로그래밍 개념을 이해하는데 작게나마 도움이 되었다. 


********************************************************************************************

 

 


오늘 선생님께 배운게 너무 많긴한데.. 대충 정리해보면(나머진 노트 참조)

1.io관련 클래스들을 볼때 구분 기준(in/out 구분은 너무 직관적이니 논외)

a.바이트 기반(c에서 /rb /wb 옵션으로 1byte단위 초간단하게 바이너리파일) vs 2byte 문자 기반(/rt /wt 옵션 텍스트파일;;) 
=> 메모장으로 열어보면 확실히 이해  (Ex) InputStream(1byte)  vs  Reader(2byte)  ,  OutputStream  vs Writer

b.노드계열(목적 스트림을 열수있는), 필터계열(어떤 방식으로 i/o 할것인가에 대해 추가or확장된 기능)
=> 오늘 요것덕에 데코레이터 패턴에 대한 이해가 한층 업그레이드
(Ex)(파일,메모리,다른 프로세트,네트웍,db등 목적지에 대한) File,Piped,ByteArray기타등등(In/Out)putStream, 

=>지금까지 스트림 객체를 생성할때 단순하게 버퍼드가 좋은거라 본게 있어서.. 멋도 모르고.. 기계적으로 생성해서 
사용했었는데.. 오늘 구분하는 법을 배웠기 때문에 , 다음부턴 내 목적에 맞는 스트림을 생성이 가능할듯 (Happy)

=>왜 노드 스트림 클래스와 보조(필터,데코레이터) 스트림 클래스를 구분한 것인가?  
목적 스트림의 종류 a(파일,네트웍,메모리,db등) * 구체적 처리방식의 종류 b(버퍼드,필터드,프린트,라인넘버 어쩌구..)
a*b 너무 많으니까.. a따로 b따로 만들어서 사용자(우리 개발자=클라이언트)가 알아서 조립해서 사용하라고 데코레이터
패턴을 이용해(개념및 구현 설명 논외) 배포함. 솔직히 모든 구체적 상황별로 클래스를 만들어 놓으면.. 그 클래스들 이름
누가외움?  (자바 api들의 수많은 패키지.. 그안에 들어간 수많은 인터페이스,클래스 조각들.. 기존에 만들어진 인터페이스
와 클래스,상속구조를 이용해 구체화된 수많은 하위 클래스들)

=>툴을 확장성 있게 만들려고 개인적으로 삽질한 설계에 대한 고뇌 + 위의 조립 개념 통해 java가 추구하는 객체 지향을 
조금 더 이해했다고 착각중임 -_-;
 
=> 모든 개념을 담을수 있는 object 타입을 루트클래스로.. 모든 클래스 타입이(예전에 reflect 보면서 놀랬던게.. object란
일반적으로 내가 심지어 class, method등도 object 타입이다. 한마디로 모든 타입과 값을 포함할수 있기에 타입 제너릭
(다형성) + value 제너릭 하다.
 
is a, has a 구성과 상속, 설계와 구현의 분리(interface , abstract class) 를 이용한 각종 디자인 패턴들.. 결국 확장과
유연성및 변경에 따른 노가다 방지를 위해 선배 개발자들이 피땀흘려 고민한 산물이 oop로 자바에 멋지게 구현되어 있다;;

=>아참.. java.io , java.net , java.sql ... 내가 웹작업 하면서 찾아보던 패키지인데.. (그제~오늘은 xml관련 꽂혔지만)
선생님 말씀으론 결국 목적지와 스트림의 형태가 약간 다를뿐 입/출력이라는 커다란 틀에서 유사점(1.스트림 연다
2.스트림으로 작업한다. 3.스트림 종료한다.  네트웍이라면 bind해서 소켓 만들고 connect로 연결요청 -> accept으로
동의 -> 하면 create로 소켓간에 스트림 열어주고?? 맞나?? -> 이런 저런 통신 주고 받다가.. -> 연결 끊고 byebye.. 
간단하게 java.net의 소켓 클래스도 InputStream getInputStream()과 OutputStream getOutputStream()을 제공해 준다;;)
(디비도 연결할 db종류 선택, 스트림 연결(Connection인가 먼가), 쿼리 쏘고 리절트셋 받고.. 웹서버도..)
(etc)모든 스트림은 기본적으로 byte인데.. text(2byte)단위로 i/o는 결국 내부적으로 encode(),decode() 해준다는 의미임..
(etc2) String형 "199"를  byte로 저장하면 (4bit 0x00  4bit  0xc7) (ancii?)  => 상위 비트에는 값이 안들어간다. 그럼으로 EOF -1
이 가능하다.   text(2byte)로 저장하면 (4bit- 0x00 4bit- 0x31 4bit - 0x39 4bit - 0x39임)

=>추가로 생각해볼점! net패키지의 소켓클래스던.. InputStream 타입으로 스트림을 리턴한다. 즉 1byte단위인 것이다.
(이런 객체들이 많다고 말씀해주심)그럼으로 InputStreamReader 라는 byte->text 로 변화해 처리해주는 클래스가 중요한 것이다. 

각설하고;;;

2.실제 잘 쓰이는 조합은

일반적인 인풋시 BufferdReader(InputStreamReader or FileReader)를 사용
 => InputStreamReader 가 존재하기에 상황따라 1(바이트기반)->2byte(문자기반)으로 변화가 가능하고.. 파일 작업도 가능하고

거의 대부분의 경우의 아웃풋시 PrintWriter(노드&필터형&1-2byte혼용&다양한데이터타입으로 만능 출력객체)

=>BufferedReader 가 엔터 데이터를 스킵하는 문제 때문에 그것을 해결하기 위해 PrintWriter 클래스의 println() 자동개행
   을 사용하고.. 그럼으로 일반적인 입력시엔 BufferedReader  , 출력시엔 PrintWriter 를 사용하는 페어가 되는 것이다.

3.버퍼드 필터 방식으로 i/o를 할때 버퍼 방식의 동작을 기억해야함.. (모았다가 쏜다.. 안모이면 안쏜다) 
리더가 리턴값으로 읽은 사이즈를 넘겨주는 것을 인식을 해야함! (1000을 달라했는데 현재 800 넘겨주고 .. 200은 아직 버퍼링
중..) 그럼으로 flush() 역할이 중요, 글고 내가 읽어 오려는 파일의 크기가 내가 담으려는 메모리 공간보다 클때.. 주의 해야함
(덮어쓰기 됨) , 버퍼드 방식으로 데이터를 읽어와서 버퍼드 방식으로 써줄경우! 읽은 사이즈 size = read() 만큼 write(buf, size)
해준다!
=>이걸 기억해야 하는게.. 앞으로 자주쓰게될 PrintWriter도 버퍼드 출력 방식임!
=>BufferedReader 클래스는 readLine() 메서드를 사용하기 위해서 사용하는 것이다. 이것은 '\n' '\r' 등 엔터를 뜻하는
   값을 만날때까지 읽어낸다. 포인트는 "엔터를 의미하는 데이터를 스킵한다는 것이다." (참고:BufferedWriter 클래스의 newLine()
   메서드가 알아서 "엔터"를 넣어준다.)   PrintWriter가 println()를 통해 개행을 자동 제공함으로 이 문제가 해결된다!!!

4.위에서 거론했지만.. 스트림을 열었을때는 잘 닫아둬야하고 .. 예외발생시 코드의 수행을 기억해야함 (finally{})
=>필터 스트림으로 노드 스트림을 감쌌을때 필터,노드 스트림 각각을 close() 해주어야 하는가?
   =>선생님 말씀으론 필터 스트림 객체의 close()를 호출하면 필터가 알아서 자기 남은 일 정리하고 노드 스트림의
      close() 호출한다고 말씀하심. (데코레이터의 묘미)   그럼으로 필터 스트림 객체만 close() 할것!

=>예외 발생시 필터스트림의 close()를 명시적으로 호출해 줘야하는 경우는 버퍼드 필터스트림을 사용할 경우..
    실제로 print() 작업을 해줘도 실제로 파일에 기록을 하지 않고 내부의 버퍼에 담아둔다. 이것을 최종적으로
    타겟 소스로 보내는 작업은 flush()가 담당한다. 그럼으로 close() 또는 flush()를 사용해야 한다. (외부 i/o 접근은
    너무 느리고, 위험성이 있기에 최소화 한다.)  (cf) 채팅 프로그램의 경우엔 버퍼드필터스트림의 생성자에 
    boolean autoFlush 를 true로 한다)

5.중요한건 아닌것 같은데.. mark(),reset()을 배웠는데.. 이게 멀티스레드 작업중에 필요한 건지.. or 예를 들어 게임 
맵스테이지 데이터를 읽어올때 1스테이지만 읽어오고 2스테이지는 나중에 읽어오려 할때 필요한건지.. 감이 안잡힘..
(예전에는 맵 전환 시점(웨이포인트등)에 이르러야 로딩을 했지만.. 물론 용량이 커서.. 시간이 걸리니까 멀티스레드로
동영상등 틀어주면서 -_-)

6. 아참.. 문자열로 디렉토리 경로 설정시 \가 아니라 \\ 해주는것은 escape문자와 구분을 위해서! (\ 한개 쓰고 울지말자)
=>예전에 정규식 공부할때도 체크했던것 같은데.. 아 정규식 표현 기억에서 날아감;;

7. 절대 경로와 상대경로도 배웠음. good! 
.\ 현재 디렉토리  .. 상위 디렉토리로 이동  \ 해당 디렉토리로 진입

=>추후 웹플밍에서도 디렉토리 이동해야 함으로 (jsp,이미지등 디렉토리일까?) 중요하다고 하심!


8.내경우 툴 프로젝트에서 xml파일 형식으로 데이터를 load,write 하는 작업을 했었는데.. java.dom2어쩌구의 
Document,Element 클래스를 활용해서 작업했었는데.. 아래를 보면.. XMLEncoder ,decoder 가 있다.. 나는 이걸 
활용해야 했었다. OTL  <-- 제일 하단에 실제 사용 소스코드 첨부! (불펌죄송)
(XMLEncoder , XMLDecoder 를 사용해서 데이터를 문서로 구성할 경우, 실제 다른 시스템과 주고 받기는 무리가
있다. 객체의 상태를 기록하고 빼오는데 사용할 수준이다.)
 
시간 낭비하지 말고 이미 잘 만들어진 API를 사용할것!@@@@@ 툴의 확장성에 대한 설계적 고민 ㅂㅂ2

public class XMLEncoder  extends Encoder{}
명세:XMLEncoder 클래스는 ObjectOutputStream 의 보완적인 대체 클래스이며,
ObjectOutputStream으로 객체의 바이너리 표현을 생성해서 JavaBean의 텍스트
표현을 생성한다. 아래의 코드를 보면 JavaBean의 그 모든 프로퍼티의 텍스트
표현을 생성할 수 있다.

(ex) XMLEncoder e = new XMLEncoder(new BufferdOutputStream (new FileOutputStream("text.xml") ) )
                          e.writeObject(new JButton("Hello World"));
                          e.close();

XMLEncoder 클래스는,JavaBean 를, XML 스펙 버젼 1.0 으로 Unicode/ISO 10646 캐릭터 세트의 UTF-8 캐릭터 세트에 준거한 XML 문서로서 표현하는 디폴트의 지정을 제공합니다. 



아래는 뭐였드라;; 
 
파일 시스템 관련

ps. 글쓰다가 세션 만료되었음.. 나는 이제 세션의 의미와 왜 세션을 종료 시켰고 내가 쓰던 글을 임시 저장해뒀는지를 
알게 되었음. jsp 책에 감사. 입출력으로도 벅찬데.. 이것 저것 챙겨보다.. 멘붕왔다. OTL

java.beans.XMLDecoder와 java.beans.XMLEncoder를 이용한 Java객체의 xml 변환

by givingsheart 2014. 1. 1. 15:51