I/O

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가 함께 공존한다. 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

텍스트 데이터 메모장에서 열어서 볼 수 있는 데이터 Java에서 복사, 분석을 할 수 있다. ByteStream에서 다룬다.

바이너리 데이터 메모장에서 열어서 볼 수 없는 데이터 열게 되면 이상한 숫자로 나오는 데이터이다. 그림, 영상, 압축파일, 각종 한글, 워드, 엑셀, 파워포인트등의 파일 전용프로그램을 통해서만 데이터를 보고 편집할 수 있다. 우리는 복사로 옮기기만 한다. 첨부파일 업로드 하는 방식이다.

우리가 확인하는 데이터는 Text Data밖에 없다. 다른 것은 전용프로그램을 통해서만 Data 확인이 가능하기 때문이다.

Stream이란

데이터를 운반하는데 사용되는 연결통로이다.

연결되는 통로로써 1차Stream과 연결되어 소스와 직접 연결하여 사용한다. 파일명을 입력하는 곳에 생성자, URL, 파일 경로를 입력할 수 있다. 그러나 속도가 느리기 때문에

연결되는 통로로써 1차Stream과 연결되어 소스와 직접 연결하여 사용한다. 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만 입력되기 때문에 줄바꿈문자는 따로 입력해줘야한다.

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 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 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를 나눠서 전체 평균으로 작성할 수 있다.

읽는 법

파일 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번 왔다갔다하는 것과 동일하게 속도가 엄청 느리기 때문이다.

일반 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

728x90

from http://lionpower.tistory.com/173 by ccl(A) rewrite - 2021-10-14 22:01:24