날아라쩡글이의 블로그입니다.
I/O 본문
728x90
반응형
I/O는 java.io package에 포함되어 있는 클래스 이다.
- App에서 리소스를 읽어오거나 App에서 데이터를 목적지로 출력하는 작업을 수행하는 클래스이다.
- 내 App이 기준점으로 자원을 읽어오면 Input File을 출력하면 OutPut 으로 방향에 따라서 읽어오는 Stream와 내보내는 Stream이 존재한다.
- 클래스의 종류의 경우 한번에 읽고 쓰는 데이터에 따라서 구별이 가능하다.
- ByteStream(바이트스트림)
- 한번에 한 1bite씩 읽고, 쓸 수 있는 스트림
- 바이너리데이타를 다룸
- 010101형태로 읽는 스트림
- InputStream, OutputStream
- FileInputStream, FileOutputStream
- BufferedInputStream, BufferedOutputStream
- DataInputStream, DataOutputStream
- ObjectInputStream,ObjectOutputStream
- printStream
- CharactStream(캐릭터스트림)
- 한번에 한글자씩 읽고 쓸수 있는 스트림이다.
- Reader, writer
- FileReader, FileWriter
- BufferedReader, BufferedWriter
- printWriter
- 한번에 한글자씩 읽고 쓸수 있는 스트림이다.
- 방향에 따라서 구별된다.
- 읽기 InputStream, InputReader
- 쓰기 OutputStream, OutputReader
- 위치에 따라서 구별된다.
- 1차 Stream, 말단 Stream
- 직접 리소스와 연결되는 Stream
- FileInputStream, FileOutputStream
- FileReader, FileWriter
- 브릿지 Stream
- byteStream과 CharactStream을 연결하는 Stream
- InputStreamReader
- OutputStreamWriter
- Input과 Output, Reader와 Writer가 함께 공존한다.
- byteStream과 CharactStream을 연결하는 Stream
- 2차 Stream
- 직접 리소스와 연결할 수 없는 Stream
- 1차 Stream혹은 브릿지Stream과 연결해서 사용하는 Stream
- 보통 2차 Stream은 자신과 연결된 Stream의 읽거나 쓰는 능력을 향상시킨다.
- 다른 Stream과 Writer, Reader와 연결해야한다.
- BufferedInputStream, BufferedOutputStream
- BufferWriter,BufferReader
- DataInputStream, DataOutputStream
- ObjectInputStream,ObjectOutputStream
- 출력전용Stream
- 출력하는 기능만 있는 Stream
- printStream, printWriter
- 출력하는 기능만 있는 Stream
- 1차 Stream, 말단 Stream
- 텍스트 데이터
- 메모장에서 열어서 볼 수 있는 데이터
- Java에서 복사, 분석을 할 수 있다.
- ByteStream에서 다룬다.
- 바이너리 데이터
- 메모장에서 열어서 볼 수 없는 데이터
- 열게 되면 이상한 숫자로 나오는 데이터이다.
- 그림, 영상, 압축파일, 각종 한글, 워드, 엑셀, 파워포인트등의 파일
- 전용프로그램을 통해서만 데이터를 보고 편집할 수 있다.
- 우리는 복사로 옮기기만 한다. 첨부파일 업로드 하는 방식이다.
- 우리가 확인하는 데이터는 Text Data밖에 없다. 다른 것은 전용프로그램을 통해서만 Data 확인이 가능하기 때문이다.
Stream이란
- 데이터를 운반하는데 사용되는 연결통로이다.
-
연결되는 통로로써 1차Stream과 연결되어 소스와 직접 연결하여 사용한다.
- 파일명을 입력하는 곳에 생성자, URL, 파일 경로를 입력할 수 있다.
- 그러나 속도가 느리기 때문에
- 2차 Stream을 이용하여 1차Stream의 성능을 높여주는 Stream을 연결하여 사용할 수 있다.
- 수도 파이프에 호스를 달면 물은 나오지만 샤워기처럼이 아닌 콸콸나오는 것처럼 2차Stream인 샤워기를 이용하여 물을 원하는데로 사용랄 수 있다.
- 2차 Stream은 1차 Stream과 연결하여 성능을 높여줄 수 있다.
브릿지 Stream이란,
- Reader는 문자로만 읽고, Writer의 경우는 문자로 작성한다.
- InputStream은 Byte단위로 읽고, OutputStream으로 Byte단위로 보낸다.
- 그렇기 때문에 서로 연결을 해줄 수 없어서 가운데에 브릿지Stream을 연결하여,
- Byte에서 한글자로 읽고, 보내는 역활을 진행한다.
- 1차 ->브릿지 -> 2차 이런 순으로 데이터를 보낼 수 있다.
FileWriter
- 모든 I/O의 경우 예외처리가 기본이다. IOException
- throws처리해도 되고, try catch문으로 진행해도 된다.
- 파일에 텍스트를 기록, 출력한다.
- text만 입력되기 때문에 줄바꿈문자는 따로 입력해줘야한다.
- write가 중복정의 되어있고, String이 반환타입이다.
- 꼭 close를 해주어야한다.
PrintWriter <입력하면 바로 이 객체를 사용하자!!!!>
- 텍스트를 출력하는 객체이다.
- write(String text)
- 보통의 출력 객체는 이 메소드만 가지고 있다.
- println(String text) 등의 메소드를 가지고 있다.
- 중복정의된 println(값) 메소드를 가지고 있다.
- println 메소드는 줄 바꿈 문자를 자동으로 추가한다.
- CSV 데이터를 기록할 때 유용하다.
- 업무용 시스템을 만들기 때문에 무의미한 데이터는 입력하지 않는다.
- 유용한 데이터는 특별한 형식으로 기록되어 있다.
- 제일 유용하다.
- writer에서는 FileWriter와 printWriter만 기억하면 된다.
BufferedReader<읽기하면 바로 이 객체를 사용하자!!!!>
- Reader에서 제일 기억해야 하는 객체
- 텍스트를 읽어오는 객체이다.
- 텍스트를 한 줄씩 읽어오는 String readLine()메소드를 제공한다.
- 텍스트를 한 줄씩 읽어오는 객체는 이 객체 하나 뿐이다.
- 한 줄을 읽고 그 줄에서 읽어올 데이터가 없으면 null을 반환한다.
- readLine() 줄바꿈 문자 앞까지 읽어서 반환한다.
- readLine()은 더 이상 읽어 올 데이터가 없으면 (Stream끝에 도달하면) null을 반환한다.
- 우리가 가져오는 text data는 CSV의 형태를 가지고 있다.
- 정형적인 데이터의 형식을 가지고 오지, 불 규칙한 데이터에서 읽어오는 경우는 존재하지 않는다.
- 정형데이터
- 규칙에 맞춰져 있어서 읽을 수 있다.
- CSV가 대표적이다.
- 한 줄씩 의미를 갖고 있어서, 한 줄씩 읽어내는 기능이 중요하다.
- BufferedReader밖에 없다.
- 반정형데이터
- 일정한 형식을 가지고 있지만 약간의 손을 거쳐야지 데이터를 읽을 수 있다.
- 데이터 분석하는 경우도 로그 Data로 반정형 데이터를 가지고 있어서 , 약간의 손을 거쳐야지 데이터를 읽을 수 있다.
- 비정형데이터
- 일반 text를 의미한다.
- BufferedReader는 위에 작성되어있듯이 2차 Stream으로 1차 Stream 혹은 브릿지 Stream이 있어야한다.
- 파일 내용을 읽어오는 FileReader객체를 생성한다.
- FileReader의 읽기 메소드는 1글자씩만 읽어온다.
- Stream의 text Data를 한 줄을 읽어오는 BufferedReader객체를 생성한다.
- BufferedReader가 읽어올 텍스트를 전달하는 FileReader객체를 BufferedReader한테 생성자 인자로 전달한다.
- 파일의 텍스트 데이터를 읽어오는 FileReader를 BufferedReader에게 전달한다.
- Stream에서 한줄씩 읽어서 text에 대입한다.
- text = reader.readLine();
- text에 대입된 값이 null 아니면 true이다.
- 즉, while문 블록내의 수행문이 실행된다.
- while((text = reader.readLine()) != null) 반복문으로 돌리고,
- String[] values = text.split(",");으로 나눠서
- 각 배열에 하나씩 입력한다.
- index상으로 1번부터는 숫자기 때문에 return type은 int로 Integer.ParseInt(values[1].trim());으로 전환한다.
- 그리고 출력해주면된다.
- 마지막에는 닫는 메소드를 입력해주어야한다.
- try~catch문으로 예외를 잡아줘야한다.
텍스트 데이터의 읽고, 쓰기
- 텍스트 데이터를 출력하기
- App에서 생성된 텍스트 데이터를 출력하기
- PrintWriter의 println()을 사용한다.
- 리소스가 파일인 경우 printWriter writer = new printwriter("c:/temp/doc/example2.txt");를 출력한다.
- 텍스트 데이터 읽기
- App에서 분석할 텍스트 데이터를 읽기
- BufferedReader의 readline()을 사용한다.
- 리소스가 파일인 경우
- FileReader fileReader = new fileReader("c:/temp/doc/example2.txt");을 작성한다.
- BufferedReader reader = new BufferedReader(fileReader);을 입력한다.
- text 파일은 다운로드하거나 첨부파일 업로드 하는 것은 위에 해당되지 않는다.
- text파일을 전송하는 것 (업로드, 다운로드 하는 것)은 위에 해당되지 않는다.
객체가 들어오는 것은 CSV파일 자동처리 라이브러리가 있다. 지금까지 파일을 기록하고 파일을 읽어봤다.
리소스가 File이었다.
리소스데이타가 파일이 아닌 URL인 경우를 확인해보자
- 파일의 경우 FileReader을 2차 Stream인 BufferedReader와 연결해주면 완료가 되었다.
- 리소스의 경로 , 주소만 있다면 전부 다 가져올 수 있다.
- String path= "";로 주소를 설정해준다.
- 쿠키가 있어야한다.
- 프로토콜, 호스트번호, 경로, 포트번호가 들어가 있는 경로를 입력한다.
- 이것을 분석해서 갖고 있는 객체가 URL이다.
- Java.net의 URL
- URL url = new URL(path);
- String객체 참조변수를 생성자에 입력한다.
- 자원이 있는 주소로, URL 주소가 가르키는 리소스를 1byte씩 읽어오는 스트림 객체를 획득했다.
- InputStream inputStream = url.openStream();
- File, Jpeg, pnp를 얻을 수 있다.
- InputStreamReader isr = new InputStreamReader(inputStream);
- byteStream과 연결되는 Reader개체를 생성한다.
- BufferedReader reader = new BufferedReader(isr);
- 한 라인씩 읽어오는 BufferedReader와 InputStreamReader객체를 연결한다.
이 3가지를 합쳐서 한번에 작성할 수 있다.
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
- 이렇게 한꺼번에 적어서 완성할 수 있다.
- 한 줄씩 읽어올 수 있다.
- 데이터에 대한 컬럼명 획득하기
- 한 줄을 버리고 싶다면 reader.readLine();으로 버릴 수 있다.
- 단 방향이기 때문에 이미 지나간 것을 다시 읽을 수 없다.
- 그렇기 때문에 while문으로 돌리기전에 사용하면 두번째 줄 이후로 출력이 된다.
- String text = null;
- reader.readLine(); 한 줄씩 출력되는 내용을 입력할 String을 설정하였다.
- while((text = reader.readLine()) != null)
- //while문은 reader.readLine()이 null값이 아니면 반복한다.
- String[]values = text.split(",");
- //text상 ,표시가 있으면 잘라서 String 배열에 넣는다.
- int amount = Interger.parseInt(values[5])
- 거래 금액이 있는 index를 amount에 입력한다.
- totalAmount += amount; 해서 totalAmount에 더한다.
- 그리고 데이터를 읽고 원하는 정보를 획득할 수 있다.
- 예외의 경우 try(이 곳에 입력하면) close();메소드를 따로 호출하지 않아도 된다.
실제 read와 write로 데이터를 획득하기
- VO class를 완성한다. getter을 입력한다.
- 입력 하기
- ScoreWriter을 입력한다.
- main메소드를 입력한다.
- List<Score> scoreList = new ArrayList<>();
- List객체에 저장된 학생성적 정보를 Score.txt파일로 저장할 예정이다.
- try (PrintWriter writer = new PrintWriter(경로 입력)) {
- StringBuilder sb = new StringBuilder();
- 향상된 for문으로 List를 돌린다.
- StringBuilder에 저장한다.
- sb.append(Score.getName());
- writer.println(sb.toString());
- StringBuilder의 toString()메소드를 호출하여 writer.println()을 이용하여 경로입력한 곳에 저장한다.
- sb.setLength(0);
- String배열에 들어있는 데이터를 0으로 만들어 버렸다.
- 데이터를 지워버리는 역활을 수행한다.
- save버튼을 만들어서 입력할 수 있다.
- 파일에 데이터를 영속화할 수 있다.
- 읽어 오기
- try (BufferedReader reader = new BufferedReader(new FileReader(경로를 입력한다. ));{
- 읽어올 데이터가 여러개의 정보이다.
- 행하나가 객체 하나에 대응된다.
- 여러개를 담을 ArrayList가 필요하다.
- HashSet은 같은 정보는 못 담으니까 순차적으로 쌓는 ArrayList에 담아준다.
- List<Score> scores = new ArrayList<>();
- Score.txt파일에서 읽어온 성적정보를 저장하는 ArrayList객체
- String text = null;
- while((text = reader.readLine()) != null) {
- text -> "홍길동,100,100,100" 으로 읽을 수 있다.
- String[] values = text.split(",");
- values -> ["홍길동","100","100","100"]으로 저장된다.
- 각자 배열의 값을 분석하여 입력한다.
- Score score = new Score (name, kor, eng, math);
- Score객체를 생성해서 분석된 성적정보를 입력한다.
- scores.add(score);
- 성적 정보가 저장된 Score객체를 ArrayList객체에 저장한다.
- 데이터 조작/ 분석하기
- 학생들의 전체 평균 점수 계산하기
- int totalAverage = 0;
- 변수의 초기화
- 향상된 for문으로 totalAverage + = score.gerAverage(); 진행하고
- totalAverage/scores.size();로 평균점수에서 size를 나눠서 전체 평균으로 작성할 수 있다.
- try (BufferedReader reader = new BufferedReader(new FileReader(경로를 입력한다. ));{
읽는 법
- 파일
- FileReader
- FileInputStram
- 메모리
- StringReader
- ByteArrayInputStream
- 네트워크
- Socket
- getInputStream()
- 인터넷
- InputStream
- InputStreamReader
- BufferedReader
text -> 객체 객체 -> text 왜 변환하는 걸까?
- 간단하게 넘어갔지만, 직렬화에 좋다는 이야기가 있다. 그건 다음시간에 다뤄볼 예정이다.
CharactStream(캐릭터스트림)
- InputStream (추상 클래스 )
- abstract int read();
- int read(Byte[] byf) {.....}
- close(){....}
- 구현클래스
- FileInputStream
- BufferInpurStream
- ByteArrayInputStream
- DataInputStream
- 구현
- readInt()
- readLong()
- readBoolean()
- readUTF()
- pipedInputStream
- FilterInputStream
- printStream
- print()
- println()
- OutputStream (추상 클래스 )
- abstract void write(int value);
- void write(byte[] buf, int offSet int len) {...}
- void flush(){...}
- void close(){...}
- 구현클래스
- FileOutputStream
- BufferOutputStream
- ByteArrayOutputStream
- DataOutputStream
- 구현
- writeInt(int value)
- writeLong
- writeDouvle
- writeUTF(String value)
- pipedOutputStream
- FilterOutputStream
- Reader(추상 클래스 )
- abstract int read();
- int read(char[] buf)
- void close(){...}
- 구현클래스
- FileReader
- StringReader
- BufferedReader
- readLine()
- InputStreamReader
- writer(추상 클래스 )
- abstract void write(int value)
- void write(char[] buf, int offSet, int len)
- void write(String text) {...}
- void close(){...}
- 구현클래스
- FileWriter
- StringWriter
- BufferedWriter
- OutputStreamWriter
- printWriter
- print()
- println()
InputStream, OutputStream은 바이너리 데이터일 때 사용함.
- 그림파일, 영상파일, PPT, 데이터들, 흔하게 만나는 데이터
- 응용 프로그램으로 파일을 생성하는것은 거의 사용하지 않는다.
- 내 파일을 어딘가에 전송하거나, 클라우드 다운, 올릴 때
FileInputStream , FileOutputStream은 파일을 옮기는 작업을 할 때 많이 사용한다.
- Copy는 전송, 업로드, 다운로드 전부 copy이다. 복사하는 방식이다.
FileCopy하기
- File을 copy하면, 같은 유니코드로 복사지만, 파일을 표시하는 매직넘버에 따라서 형태가 달라진다.
- 복사를 받는 반환타입은 int의 값으로 3Byte는 0으로 출력 1Byte에만 값을 담는다.
- 바이너리 데이터는 Input/ outPut으로 업로드와 다운로드작업을 빈번히 사용한다.
- 입출력시 BufferedInputStream을 사용하는 것이 좋다.
- 일반 InputStream의 경우 1Byte를 옮기게되는데, 그렇다면 1층~ 10층까지 택배 100개를 옮기면 100번 왔다갔다하는 것과 동일하게 속도가 엄청 느리기 때문이다.
- 2차 스트림인 Buffered를 사용하면 속도가 엄청 빨라지는데, 1번에 8KB씩 옮기기 때문이다.
복사 객체 만들기
- FileInputStream in = new FileInputStream("경로");
- 원본파일을 1byte씩 읽어오는 Stream을 생성했다.
- FileOutputStream out = new FileOutputStream("복사될 경로");
- 복사본 파일을 생성하고 1byte씩 출력하는 Stream객체를 생성
- 파일이 얼마나 큰값인지는 모르지만 파일의 맨끝은 -1로 저장된다.
- int value = 0;
- 1byte씩 읽은 값을 저장하는 변수
- while((value = in.read)) != -1){
- 1byte씩 읽어서 value에 저장하고, value에 저장된 값이 -1이 나올때까지 수행문 반복한다.
- out.write(value);
- value에 저장된 값을 복사본파일에 꺼내서 저장한다 .
- in.close()
- out.close()
- copy code는 이게 끝이다.
링크된 파일사진을 다운받기
- URl url = new URL("링크 주소");
- InputStream in =url.openStream();
- 반환타입이 inputStream으로 연결되어 있다.
- FileOutputStream out = new FileOutputStream("다운받을 경로. 유형");
- 복사본 파일로 1byte씩 출력하는 스트림객체를 생성
- 다른 컴퓨터로 보낼 수 있다. 그때는 FileOutputStream객체를 사용안함.
- int value = 0;
- while(((value = in.read()) != -1) {
- out.write(value);
- }
- in.close();
- out.close();
- 자원의 누수를 막는 close();를 꼭 설정해줘야한다.
BufferedInputStream 과 BufferedOutputStram을 이용하여 읽기, 쓰기 속도를 향상 시키자
- long beginUnixTime = System.currenTimeMillis();
- 시작과 끝의 유닉스 타임을 비교하기 위해 유닉스타임 코드를 작성함
- FileInputStream fis = new FileInputStream("복사할 파일 경로 입력");
- FileOutputStream fos = new FileOutputStream("복사해놓을 파일 경로 입력");
- BufferedInputStream in = new BufferedInputStream(fis);
- BufferedOutputStream out = new BufferedOutpuutStream(fos);
- InputStream과 OutputStream으로 읽기 쓰기 속도를 향상시키는 2차stream이다.
- int value = 0;
- while((value = in.read()) != -1) {
- out.write(value);
- }
- fis.close();
- fos.close()
- long endUnixTime = System.currenTimeMilis();
- 소요시간 : endUnixTime - beginUnixTime
반응형
'중앙 HTA (2106기) story > java API story' 카테고리의 다른 글
Stream메소드 사용법 (자바 8버젼이상) (0) | 2022.01.03 |
---|---|
I/O(Data, Object)와 직렬화 (0) | 2021.10.18 |
사용자 정의 예외 처리 , 앞으로 코딩 작성 방법(맨 밑) (0) | 2021.10.13 |
Formating (포맷팅) (0) | 2021.10.08 |
Random class (0) | 2021.10.08 |
Comments