국비지원학원/Java

44~46일차

초코맛 2019. 1. 14. 23:13
반응형
*IO Stream(Input/Output Stream)

  • <처리해야할 대상이 JVM밖에 있어서 밖에서 가져오고 내보내는것.
  • JVM외부에 존재하는 데이터를 처리하기 위해 사용하는 클래스들
  • <대표적인 예가 모기(사람에게 대로 피빨아먹는거? 어렵다??)
  • <class를 만들면 클래스내에 선언된 데이터들로, 여태 내 안에 있는데이터를 가져다 사용했는데, 이젠 밖!
  • java.io package에서 관련클래스를 제공한다.
  • 단방향io  (읽기스트림은 읽기만, 쓰기스트림은 쓰기만 가능)    (<Stream은 읽기아니면 내보내기 하나밖에 하지 못한다.)  (하나의빨래로 먹으면서 밷는게 불가능한것처럼)
  • io는 8bit Stream(byte기반 Stream)과 16bit Stream(문자열 기반 Stream) 2가지가 제공.
  • <8비트 스트림이 먼저나왔고 다른나라의 언어를 처리할 필요성때문에 문자열기반이 만들어졌다.
  • 8bit Stream
    • 모든데이터를 읽고 쓸 수 있다.(파일,오브젝,기본형 데이터형들)
  • 16bit Stream
    • 문자열 데이터만 읽고 쓸 수 있다.
  • <클래스는 설계도이고 설계도로 만들어진 객체 instanse가 JVM에 올라가게 된다. 인스턴스에는 int String등등이 있는거고 입력은 입력의 근원지 출력은 출력의 목적지라고 한다. 컴퓨터에는 각각 3가지 뿐이다


java.lang.System
throwble이 가장 윗부모 ~~


InputStream
8bit
16bit
InputStream


Reader


DatainputStream
FileInputStream
ObjectInputStram...
BufferedReader
FileReader
InputStreamReader

OutputStream
8bit
16bit
OutputStream


Write


DataOutputStream
FileOutputStream
ObjectOutputStram...
BufferedWrite
FileWrite
OutputStreamWrite
  • 8bit Stream과 16bit Stream은 결합하여 사용할 수 있다.
  • 8bit는 =   (속도가 더 빠르다/한번에 움직이는 데이터의 양이 적다.(속도와는 별개)=>시냇물이 좁은게 더 빠른것 처럼)
  • 16bit는 ㅁ 2배 만함   (속도가 느리다/데이터의 양이 많다.=>이걸 보완하기 위해 섞어 사용하는 것)
  • <넓어지다 좁아지고 다시 넓어지면서 속도가 빨라져 잘섞인다???



*입력 Stream
  • 키보드 입력
    • System.in은 InputStream이다.
    • ex)
    • System.in.read()
    • <키보드는 마더보드에 연결되어있고 키보드 버퍼에 하나하나 담긴다 size가 256개 라서 연속적으로 그이상의 크기가 들어가지 않는다..(SQLPLUS같은 경우!해당됨) 마더보드를 관리하는게 os인데, os에서 명령이 전달되어 입력되는걸 그대로 처리하면(리트렌디랄?인텔) 꺼꾸로처리하면(빅엔디안?) CPU에따라 다르게 처리....  그리고 그위에 JVM 그위에 클래스(instance) JVM에서 os에 콬꽂아놓았는데(명령을 처리하는곳까지) 그게 System.in 그게 인스턴스까지 와서 read()...쭈왑 올려줌.
    • 입력순서대로 그대로 입력: intel계열 cpu  =>Little Endian
    • 입력순서를 거꾸로 처리 : RISC계열(Mac) cup  =>Big Endian
    • InputStream의 method IO는 컴파일예외로 꼭~!처리~!



package day1219;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 사용자가 입력한 키보드의 값을 처리하는 System.in
* @author owner
*/
public class UseKeyboardInput {
     public UseKeyboardInput() {
     
           System.out.println("아무키나 누르고 엔터");
           //3.입력된 모든 문자열 을 받고 싶다!!
           //3.8bit Stream과 16bit Stream을 연결
           BufferedReader br= new BufferedReader(new  InputStreamReader(System.in));//으로 Stream연결
           
           try {
                //1.입력값중 최초 입력 문자 하나 받기
//              int input=System.in.read();
                //<read 는 블록method 차후 동작이있어야 아래로  진행이되는 method이다.
                //read는 8bit라 한번에 하나..(맞나?)
//              System.out.println("입력값 : "+input);//<a가  눌린지 키보드는 모른다?키코드 값65만 알뿐.
                //키코드에대한 유니코드?읽어주는거라고?
                //키보드 버퍼는 키코드 값을 가지고 들어가는데,  os에서 key가 눌리기전에 key에대한 조합을 문자로 변경해  유니코드값으로 자바가상머신이 읽게된다.
                //그래서 대문자 소문자가 다른 유니코드를  가지기때문에 다른결과가 나오는것.
                //키를 누르면 os로 갔다가 자바가 빼오는것?ㄷ
                
                //2.입력된 모든 문자열 받기 : 한글은 받을수 없다.
//              int input=0;
//              while(true) {
//                   input =System.in.read();
//                   System.out.print((char)input);//char로  캐스팅하면 넣은대로 나온다..문제는 한글이 안됌..
//                   if(input==13/*Enter의 값*/) {
//                         break;
//                   }//end if
//                   //if문을 막으면 13과 10이 나오는데, \n과  \r이 출력되는것. window에는 붙는다?
//              }//end while
                
                //16bit Stream을 사용하여 입력된 데이터를  줄단위로 읽어 들인다.
                String str=br.readLine();
                System.out.println(str);
                //스트림 사용이 끝났으면 스트림의 연결을 끊는다.
                br.close();
                
           } catch (IOException e) {
                e.printStackTrace();
           }
     }//UseKeyboardInput
     public static void main(String[] args) {
           new UseKeyboardInput();
     }//main
}//class


*Stream의 연결(스트림은 연결가능)
read로는 한글을 입력받을 수 없어 한글을 입력받기 위해 8bit와 16bit를 함께 사용해야함.
마더보드 ; 속도를 올리기 위해 메모리에 적제. System.in은 한글이 안돼는데,,,그대로 얻어와 확장을 해주어야 한다.8bit는 한글이 깨짐.16bit는 한글이 깨지지 않는데 두개를 연결하려면 크기가 달라 이어지지 않는다. 연결을 하려면 또하나의 관이 필요한데, BufferedReader 
로  작은관을 큰관으로 연결시켜 준다.


 
-키보드 입력      -8bit와 16bit Stream에 결합. 읽어들인 charset을 변환   -속도개선, 줄단위로 읽는 기능.(readLine) 한글까지 다.
InputStream is = Sytem.in;
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
readLine()으로 br을 가져오고, String로 '가나다'


BufferedReader br =new BufferedReader(

                new InputStreamReader(System.in));
try{
String s= br.readLine();
}catch(IOException ie){//별로 문제가 발생하지 않아 할 일이 없다..
    ie.printStackTrace();
}



*File에서 입력(HDD에 존재하는 자원)
  • FileInputStream(8bit)
    • 파일에서 읽어들일때 모든 형식의 파일을 다 읽어들일 수 있다.(이미지,동영상,문자열..dos,console(읽어들이는거지 보여주는건 안됨)에서 뿌려줄수 없기때문에 입력받아 복사할때 쓰인다.)(메일에 첨부파일 같은거)
  • FileReader(16bit)
    • 문자열이 들어있는 파일을 읽어들일 수 있다.(독자포멧으로 만들어지지않은 파일 txt같은것)
    • 확장자가 특정된 doc,pptx,.. 독자포멧으로 된 파일은 읽어들여봐야 읽을수 없다 그 프로그램이 필요하기떄문.
  •  
  • File : File의 정보를 얻는일 / directory 생성 / File 삭제
  • 1.생성)
    • File file = new File("경로");       
    • 경로 : c:/dev  로도  c:/dec/test.txt   로도 가능하다.
  • 2.일)
    • 파일의 크기(길이)
      • file.length()  =>반환형 long
    • 파일인가?
      • file.isFile()  =>반환형 boolean  file이면 True, 아니면 false
    • 폴더인가?
      • file.isDirectory()  =>반환형 boolean  이면 True, 아니면 false
    • 읽기 가능한지?
      • file.canRead()  =>반환형 boolean   이면 True, 아니면 false
    • 쓰기 가능한지?
      • file.canWrite()   =>반환형 boolean 이면 True, 아니면 false
    • 실행 가능한지
      • file.canExecute()     =>반환형 boolean 이면 True, 아니면 false
    • 숨김 파일인지?   (보안상 건들이지 못하게 숨긴다)
      • file.isHidden()   =>반환형 boolean 이면 True, 아니면 false
    • 폴더내에 모든 폴더나 파일을 얻기
      • file.listFiles()   =>반환형 File[] 배열로나와 for로 얻을 수 있다.
    • 파일 삭제
      • file.delete()    =>반환형 boolean 잘지워지면 True, 아니면 false
    • 디렉토리생성
      • file.mkdir()    =>반환형 boolean 이면 True, 아니면 false  //root부터 생성하는 디렉토리는 생성불가.c:/dev만들수 없었었다..(지금은같음)
      • mkdirs가 붙어도 지금은 차이가 없지만, 어느 경로의 디렉토리든 생성가능했다.c:/dev만들수 있다.
    • 파일의 마지막 수정날짜
      • file.lastModified()  =>반환형long
    • 파일의 경로
      • file.getPath()    =>반환형 String
    • 파일명  "test.txt"
      • file.getName()  =>반환형 String
    • 파일의 절대 경로   "c:/dev/test.txt"
      • file.getAbsolutePath()     =>반환형 String
      • 규범(단하나의)경로(CanonicalPath)는 무조건 대문자.(C)
    • 파일의 규범경로 : 파일에 접근하는 단하나의 유일한 경로(드라이버가 대문자~!)   "C:/dev/test.txt"
      • file.getCanonicalPath()     =>반환형 String
    • 상대경로와 단축아이콘
      • 이 더있다?경로의4가지?  문제가일어났던 심볼릭 패스!지금은 고쳐짐..(상위권한이 얻어져서??)
    • 파일이 존재
      • file.exists()    =>반환형 boolean 이면 True, 아니면 false
    • 파일명 변경
      • file.renameTo("변경할 이름");     =>반환형 boolean 이면 True, 아니면 false
*File 내용 읽기

HDD에 저장된 c:/dev/temp/java_read.txt (파일)
한바이트씩 쪼개 읽어들인다(읽어들일게 없을때까지)  
-1바이트인 영어는 상관이 없으나(7bit사용, 맨앞자리는 부호)
-한글은 MS 949 2byte로 쪼개진다...
F.I.S
FileInputStream fis
=FileInputStream(file);
빨대 쮸왁
  • JVM은 Memory(RAM)에 올라가고,
  • JVM에 instance가 올라가진다.
File f= new file(경로);
FileInputStream fis=new FileInputStream(f);
//라면 한번에1byte인 영어는 상관이없지만
//한글은 한번에 1byte씩 잘려 나와 그대로 넣으면 byte수가 맞지 않아서 출력은 x
//따라서 16byte와 함께 써야 한다.
int i=0;
while((i=fis.read())!=-1){  //-1은 더이상 읽어들인 내용이 없다는것, 따라서 읽어들일 내용이 있을때 까지~!인것.


=>Stream : 자바에서 데이터를 읽고 쓰는 동작은 I/O Stream 으로 일어나는데, 네트워크도 해당됨.

=>데이터를 읽어들일때(부를 때)는 InputStream을 상속받은 class

=>데이터를 쓸때(저장할 때)에는 OutputStream 을 상속받은 class를 사용

=>직렬화 : 객체나 데이터를 저장할 때 컴퓨터가 읽기쉬운 포매승로 저장하는것,

=>역 직렬화 : 이걸 다시 메모리로 불러와 저장된 시점의 상태로 복구하는것이 역직렬화

 

 

*8bit + 16bit연결하여 출력하기
  • File f= new File("C:/dev/temp/java_raed.txt");
  • FileInputStream fis = new FileInputStream(f);
  • InputStreamReader isr = new InputStream(fis);
  • BufferedReader br = new BufferedReader(isr);
  • String temp=0;
  • while((temp=br.readLint())!=null){    //객체라서 읽어들인게 없으면 null이다.
  •      temp
  • }
  • br.close();  //메모리 누수를 막기위해 끊어준다. 각각 객체화를 해주었기 때문에 (이름을가지고 저장해서) 각각 끊어주는게 좋다. 하나 끊어도 끊어지는거기 때문에 끊어지기는한다~~
=(동일한 코드 이다.)
  • BufferedReader br =new BufferedReader(
  •         new InputStreamReader(
  •                new FileInputStream((file)));
  •                   ...
  •               br.close();  //하나만 저장했기때문에 하나만 끊으면 된다
*16bit Stream으로만 한글파일 불러오기
 
  • 16bit파일이 한글이라면~!~!~!~!=>영어일땐 8bit여도 상관 없)
  • File f= new File("경로");
  • FileReader fr= new FileReader(f);    
  • BufferedReader br =new BufferedReader(fr);
  • =>한줄로
  • BufferedReader br =new BufferedReader(new FileReader(file));
=>결과는 같으나 원천이 한글만이루어진 파일이면 굳이 8bit를 썪어 사용할 필요가 없다.

 


*메모장 읽어들이는 기능 구현



*출력스트림
-File출력
  • 8bit Stream
  • FileOutputStream //HDD를 가장 확실하게 지우는 방법은 디가우저?포멧은 파일은 그대로두로 헤더정보만 지우는꼴 살릴수 있다..덮어써도 지워짐
  • //입력된경로에 파일을 생성 없으면 생성하고 파일이 존재하면 덮어쓴다.
                                                                                                         

 

1.File 생성
File file = new  File("C:/dev/temp/java_write.txt");
2.Stream 생성
FileOutputStream fos =new FileOutputStream(file);
3.스트림에 데이터를 쓴다.
fos.write(정수);//목적지 파일에 써지는게 아니라 Stream에 통로에 써진것.
4.스트림에 기록된 데이터를 분출
fos.flush();//모든 데이터형은 분출해야 한다.
//3번과 4번은 세트지만 기본형 데이터는 flush를 하지 않아도 되기는 하다.
//출력할때는 안나오지만 분출은 잘됨.
5.fos.close();
//String형은 쓸수 없다.(8bit니까~!)

 

*문자열 쓰기
  • 16bit(한글~!~!쓰기위함~!~!)

JVM에 올라간 instance에 String데이터가있으면~!~!
  • 1.File생성
    • File file = new File("c:/dev/temp/java_write2.txt");
  • 2.Stream 생성
    • FileOutputStream fos =new FileOutputStream(file);//파일이 쨘 만들어짐.
    • //얘로는 한글을 쓸수 없다.
  • OutputStream
    • OutputStreamWriter osw=new OutputStreamWriter(fos);
    • //속도가 떨어져 하나더 붙이게 된다. 그게 버퍼!=> BufferedWirter
    • BufferedWirter bw=new BufferedWriter(osw);
  • 3.Stream기록
    • bw.write(d);     String d= "안녕하세요";
    • input과 같이 BufferedWirte?와 JVM사이에 써진다.
    • <참조형같은경우 크기를 알수 없어 분출할 수 없다. 꼭 따로 분출이필요..! 하지않으면 나가지 않는다.
  • 4.Stream에 기록된 내용을 목적지로 분출
    •  bw.flush(); //분출로 파일까지 
  • 5.BufferedWirte의 close()
    • bw.close();
=>HDD의 파일을 읽어들이려면 파일을 생성(경로+파일명)

=>File에 붙은 FileOutputStream/FileInputStream을 생성하고

=>속도를 위해 버퍼를 붙여 연결시켜 준다.

=>그리고 Stream 에 기록 ---> 분출

=>Stream 은 사용 후에는 꼭 close()로 닫아준다.(누수가 발생할 수 있다.) 

=>8bit 전송으로는 한글이 쪼개져 제대로 조립되지않아 16bit로된 Stream(read/wirte) 을 붙여줌으로 한줄씩 출력되게 해준다.

*IO Stream


-파일 복사
  • <파일을 불러들여와서 같은파일을 만들어여?

    파일을 FileInputStream 을 타고 JVM에 들어와 입력스트림의 while() read로 읽어들인다. (-1이 아닐때 까지 1byte씩 꺼냄)

    그리고 FileOutputStream 으로 flush 로 분출되어 복사된다.

-Object Stream
  • <객체는 스트림을 타고 나갈수 없다..!
  • 객체(instance) 는 Stream을 타고 JVM밖으로 나갈 수 없다.
  • 스트림은 존재 (객체는 정보를 담고있어서 나갈수 없다=중요한정보를 가질 수 있어서) 크기를 몰라 자를수 없다.
    • 중요한 정보도 가지고 잇기는 하지만 크기를 알수 없기 때문에 몇개의 byte로 나와야하는지 몰라서 
  • 기본형 데이터형은 Stream을 타고 JVM밖으로 나갈 수 있다.  (객체클래스 안에?존재) 크기가 정해져있어 알수있어 자를수 있지만 
    • 크기를 알수 있기때문에 (잘라서)내보낼수 있다
  • 밖으로 내보내려면~
  • 8byte Stream
    • -ObjectInputStream
  • JVM외부의 객체를 읽기 위한 Stream
    • -ObjectOutputStream 
  • JVM내부의 객체를 내보내기~
  • 객체가 Serialization(직렬화)
    • 모든객체가 직렬화가 되지는 않지만 JVM외부로 나갈 수 있다.
    • Serializable interface를 구현한 객체에 한해서 직렬화 할 수 있다. (그냥은 나갈 수 없다)

      JVM에  ObjectOutputStream - FileOutputStream 으로 HDD의  File과 연결 

    •  FileOutputStream fos=new FileOutputStream(file);//내보내는?일을 할수 없어. 파일을 생성하고 기록하는일..주로
    • ObjectOutputStream oos = new ObjectOutputStream(fos);//직렬화된 객체를 내보내는 일
    • oos.wirteObject(객체명);//스트림에 객체를 기록
    • oos.flush();//목적지로 분출
    • //일정크기로잘라 줄세우는걸 Marshalling 그걸 그대로 전달하여 기록한다. 쪼개진객체를 다시쓰려면 합쳐야 한다.
    • //=>object을 File에 기록했다?
    •  
    • 직렬화를 방지
      • : 변수앞에 접근지정자로 transient를 붙이면 그변수를 붙이면 JVM외부로 나갈 수 없게 된다.
      • String은 직렬화가 되는데, transient가 우선되어 직렬화가 방지된다.
    • 객체가 직렬화되서(쪼개져서) 기록이 되었는데...
    • FileInputStream fis = new FileInputStream("파일명");
    • ObjectInputStream ois = new ObjectInputStream(fis);
    • B(클래스?인스턴스?) b = (B)ois.readObject();

       

 

값을 사용하고 값을 다시 되돌려보내는 경우
은행                                                  사용자
                        공인인증서

나갔다 들어온 애한테 내가보낸게 맞는지 그대로인지 ->시리얼버전uid + 해시코드

 

 

=>객체는 스트림을 타고 JVM밖으로 나갈 수 없는데, 직렬화되어 나가는게 가능해 진다.(모든게 가능한건 아님)

=>Serializable interface를 구현한 객체만 가능.

=>transient를 붙이면 직렬화가 방지되어 JVM외부로 나갈 수 없게 된다.

=>여태 에노테이션을 붙여 경고를 지워왔던게 내가생성한 파일의 ID를 만들으라는 것이었는데,

=>은행-공인인증서-사용자의 관계 같은...

=>나갔다 들어온 애가 뭘뭍혀들어오는건 아닌지? 시리얼버전 uid+해시코드로 알아볼 수 있다.

 

반응형

'국비지원학원 > Java' 카테고리의 다른 글

51~52일차  (0) 2019.01.16
47일차~50일차  (0) 2019.01.15
43일차  (0) 2018.12.20
42일차  (0) 2018.12.20
41일차  (0) 2018.12.20