[DAY26_1] OutputStream, BufferedOutputStream, InputStream

NA YE SOM·2023년 8월 3일
1

OutputStream

FileOutputStream

★★★ex01() 이해하기!(outstream 90%해당)


이름이 outputstream으로 끝남(자식들이)

출력 클래스의 슈퍼클래스(부모역할)을 수행

스트림(stream) : 출력할때 사용하는 통로 (ex) 도로

컴퓨터에 저장되는 모든 기본 데이터 타입 : byte(바이트)
-> 모든 스트림들은 byte를 내보내거나 읽어들이는 용도로 씀(기반)

byte하나씩 하기에는 용량이 많아서 -> "byte [] 배열" 타입으로 함

-> File 객체 : 파일이나 디렉토리를 만들거나 각종 정보를 얻어낼때 씀

-> / 윈도우에서 가능

가장 먼저 ) 디렉토리 만들기(없으면)


-> 항상 "s" 들어간 버전으로 만들기
-> 파일 객체를 이용한 디렉토리 생성완료


-> 파일이 저장되는 폴더 : Parent, 그 안에 폴더 : 자식


-> dat(데이터저장용이라는 뜻으로 확장자 줌)
"ex01.dat" 파일 우리가 다룰 파일

출력 stream - 내보내는것(모니터로 하면 : 화면 출력)
(파일로 내보면 : 파일로 데이터 내보내는 것)

-> 각 데이터 스트림을 파일로 지정해주면 '파일로 만드는 용'으로 씀
(대상이 모니터로 되어있는 바이트 출력 스트림 중에서 모니터를 대상으로 하는 출력 스트림이라 system.out : 출력 데이터가 화면에 나옴)


-> 우리는 스트림을 만들어서 파일로 지정해줌 (file 객체로)


-> file객체를 써서 데이터를 넘겨서 ex01.dat에 파일객체를 쌓겠다

FileOutPutStream : 파일로 바이트 데이터를 내보내고자 할때

fout(file out으로 이름정함)


-> 선언만(아직 만들지않음)


-> file객체를 목적지로 전달하는 방법있음
-> 출력 stream의 목적지가 file 로 정해짐

-> 오류나는이유 : 생성자부터 예외처리를 요구해서
-> 선언과 생성을 분리(scope조정때문에)

try- 이때 해주기

int 단위가 4byte(바이트)

읽어들일때를 대비 : char(2바이트짜리로 저장시킬것) -> 한글자만 저장시키겠다

바이트 기반의 출력 스트림은 int아니면 byte[] 배열이라
char출력하는 방법이 없어서 그래서 쓰는것뿐

byte[] 배열 만들기

getBytes : String을 byte 배열로 바꿔주는 메소드

1.getBytes() 파라미터 x -인코딩할 필요 x

2, 3 charset을 전달하게 되어있으인까 - 인코딩 필요 O

2.get 인코딩


-> 우리나라에서 사용하는 char set : 한글처리를 위한
지정할 필요가 있으면 지정하라는 것

-> pple은 영어라서 첫번째꺼 파라미터 없는거 호출해도 상관없음


-> 내보낼 수 있는거 2개 준비 : int , byte[]


-> 세번째는 바이트배열의 일부만 보냄
-> 첫번째꺼 쓰기


-> 총 5글자를 ex01.dat으로 보내게 됨

catch 블록 하기


-> 반드시 printStackTrace넣어서 예외가 어디서 발생하는지 추적할 수 있게 함

-> finally : 항상 마지막에 수행되는 부분

예외 여부와 상관없이 fout out stearm은 닫아줘야 하는데
문제 발생


-> unhandled exception 위에서 예외 처리했는데 왜 또 요구하는가?

-> 예외처리가 필요한 애들은 try안에 들어가있어야 함


-> fout.close도 try안에 있기를 원함


-> try 안에 fout.close를 넣는것

-> 만약 이쯤에서 예외발생시) wirte b, close 안하고 바로 catch로 들어감

-> 그래서 fianlly로 뺐더니 오류가 나는것


-> 여기서 예외 발생하면 fout못만들고 넘어가는경우도 있음


-> fout은 null이니까 nullpointexception 발생
-> 못만들고 넘어가면 null값을 close(닫으라는 이야기)임

-> fout != null fout이 null이 아니면


-> finally가 존재하는 이유 fout.close() 한줄 때문에 try로 감싸기 위해서

close 까지한다음에 작업을 수행해야함


-> 파일 ex01.dat이름을 파일객체로부터 가져오는 방법

getName

getParent : 폴더를 가지고 오는것

getPath :

getPath : 경로하고 파일이름(parent랑 name 다 가지고오는것)


-> 파일크기 가져올때는 length 단위로 하면 됨

file.length()

-> 자바가 파일을 만들고 apple이라는 단어를 넣어주고 파일의 크기를 확인할수있게 코드도 넣음

영어 : 한글자 : 1byte
apple : 5글자 : 5byte 맞음



-> 원래는 열린다는 보장이 없지만 일단 메모장으로 열어봄



-> checked exception 이다(IO EXCEPTION)


-> 정상적으로 닫히지 않은 상태라 파일이 잘 안만들어짐
-> 예외처리 필요


-> try 추가로 들어감

ex02() "안녕하세요" 보내기, 파일 크기 확인

getBytes 메소드는 인코딩을 지정하는 것 가능 : string을 저장하면 string을 가져옴



  • utf 파일 한글 한글자 : 15바이트 정상
    - 한글 : 3바이트

ex03()_BufferedOutputStream("안녕하세요, 반갑습니다")

\n어디에 넣어도 상관없음

출력할때 바로 바꿔서 보내는 방식

StandardCharsets. : UTF_8 인식하고 똑같음

Char.set을 이용해서 UTF-8만드는 방법 : Helper class라고 character.set 도와주는애들


30 바이트 뛰는거 1바이트

int는 원래 4바이트인데 저장은 1바이트만 기록
실제로 저장되는 1바이트만 기록되는 것

★★★ex03()_BufferedOutputStream


: 파일출력시스템 _> 버퍼 출력시트림으로 바꾸기

(내보내는 속도는 동일한데 1바이트씩 줄줄히 내보내는애 - fileoutputstream
속도가 같더라도 buffer라는 장소에 실어서 내보내는 애 -
buffer출력stream (buffered outstream)


-> buffer출력 스트림 : 속도향상을 위해서(한번에 내보내는것)



-> 파일객체 요구하지 않고 또다른 outputstream 객체를 요구함

-> 파일을 바로 넣는것 아니라 1,2장에서 만든 fileoutputstream을 만듦

1번을 만들고 파일쪽으로 통로를 만들고 거기에 2번 buffer을 추가해서 보내는 방식


-> stream 생성하는 방법만 달라지고 나머지 1,2번은 똑같음


-> 여기서는 fileoutputstream이 메인스트림
-> 혼자쓸 수 없음

-> 이미 3번 파일 만들었는데 다시 3번 파일만들라고 요구하면 ) 자바는 "덮어쓰기"함


10시 21분 에 만든 것
-> 재실행하면 시간 바뀜

★★★(실무)에서 많이쓰임 : 일반적인 Outputstream이다 하면 ) BufferedoutputStream 쓰면 됨-> 안보고 쓸수있게 외우기!

대상을 바꾸기만 하면 업로드,다운로드 개념임

서버에서 내보낸다 -> cilent(사용자)들에게 정보를 보낼때) 대상만 파일이 아니라 '사용자'로 지정하면 됨

다운로드 비슷, api 보낼때 필요한 작업 수행가능

기타

ex04()_ java.io.DataOutputStream(변수출력시 사용)




데이터 보낼때)

dataoutputstream: wrappering된 데이터 를 제공하는것

bytes로해도됨(영어는 1byte)
chars로 하겠음

-> 한글처리 UTF처리하라고(인코딩을 바로 WRAPPING해서 보낼수있음)



-> 연결프로그램으로 메모장 연다고 보이지 않음-> 변수값 그대로 저장한거라 txt화되어서 보이지 않음

-> 정상적으로 잘 갔는지 확인하려면 '읽어보는것' 해야함


객체 내보내기

java.io.ObjectOutputStream (자주사용하지x)

ex05()_Student class : student 기반의 해당객체를 파일로 보내는 것

stream 통로

:fileoutput stream은 사용하면 데이터를 하나씩 하나씩 보냄


:objectoutputstream은 객체가 스트림에 담아지지 않아서 보낼수없음
-> 객체를 "직렬화"과정을 거쳐서

(ex) 김밥

객체(썰기 전 김밥)
직렬화(썰어 놓은 김밥)

김밥을 썰지않고 통째로 보내면 안됨(통김밥은 갈 수 없음)
-> 직렬화 과정(잘라서)을 거쳐서 하나씩 하나씩 보내야 함
(김밥을 한알씩 보내야 함)

★★직렬화 : 개체를 잘게 쪼개서 보낸다.

: 개체를 직렬화(serializable) 한다는 것 : 어디론가 스트림(stream)해서 이동시키기 위해서이다.

보내는 김밥이 2개이면 김밥을 이어서 붙여야 함 -> 잘 이어서 붙어야함(같은 김밥을 붙여야 해서: ID값을 붙여서 보냄)

1번밖에 코드짤건 없음


-> 직렬화할 수 있는 student 잘게 쪼갤 수 있는 student

경고메시지
2번임 ( 뜨는 이유)
정상적으로 조립할 수 있는 보장이 없다


-> default값 만들지 말고 gernerate 하기




-> 2번째꺼 쓰기


객체 보낼때 하나 보내는거니까 한줄만

InputStream 읽어들이기 : outputstream 반대 통로 만들기

파일 5개 준비




-> storage에 우리가 읽어들여야 할게 있으니까

파일까지 있어야 되는상태라서 directory 읽어들이는 건 의미 x


-> 파일 열어줄때랑 닫아줄때랑 try catch 써야함



출력은 없으면 만들지만, 입력스트림은 반드시 파일이 있어야 함


-> 첫번째 파일에 apple있음

읽는게 어려움( 나가는건 write쓰고 나가 하면되지만, read는 얼마나 읽어야 하는지 모르니까 어려움)
-> 실무에서 몇글자있는지 알수 없음

read : 입력 메소드


-> 입력 단위가 int 아니면 byte배열이라서


-> 초기값 0으로 잡기, 사용하려는 뜻은 아니라 초기값지정 없을시 간혹 컴파일 오류남

read를 5번 호출하는데 6번째 호출하면 더이상 읽을것이없음
a
p
p
l
e
6번째 read가 돌아갈때는 읽은내용이 없음
(read 하나당 한개의 데이터를 읽어옴)

반복문임(한글자씩 여러번 읽어야 하니까)

읽어들일 데이터를 누적할 데이터 있어야함

-> Stringbuilder 기본클래스라서 import안해도됨


-> 첫번째 파일로부터 데이터를 하나읽어서 c에 저장해라('a'를 읽어와라)

-> 이렇게 코드를 짤수없으니 반복문으로 계속수행할수있게 해줘야함

한글자읽어서 stringbuilder(sb.append) 에 두고 계속 저장(누적)을 시켜야함

while문 세우기

c는 fin.read로부터하나읽어와라 () 먼저 처리

-> 대문자 'a'에 저장할때 int에 저장될때
A의 코드값(65)로 저장됨

아스키코드 3개 외우기 ( A : 65, a : 97, 아라비아 숫자 0 : 48) -> 시작값들 외우기

-> 저장할때 ) char로 바꿔서 누적해야 우리가 알아볼 수 있음

-> 시작부터 char로 바꿀 수 없음(이유: 입력단위가 int, byte[]밖에 없어서)


-> 하나씩 읽을꺼면 : int쓰고 여러개 읽을거면 bytep[] 써라


-> stringbuidler, buffer쓰면 무조건 toString써야함!!


->

입력스트림은 꼭 안닫아도 됨(이미 위에서 다 읽어서) -> 완성된 파일을 읽어들이는 거라

생성은 안닫으면 자기한테 데이터가 계속 올거라고 생각해서 파일이 완성 x

항상 close는 try 꼭 해야함


-> 생성하다가 오류 발생할수 있으니까 null이 아닌지 확인하고


-> ★예외추적할 수 있게

ex02() ★ 더 빠른 버전

api를 통해서 서버로 부터 데이터를 읽어드린다(데이터가 써있음)
(ex) 문자구나 알 수 있음

-> 선언해놓고 써도 실무에서 문제 없음

-> 여기서부터 byte로 바꿔서 읽는 연습

3바이트2바이트1바이트도 읽을수 있다는것

-> 4byte를 못읽수도 있음
-> 두번째 크기 : 15byte
-> 3byte남음
(읽을 수있는만큼만 읽는것)


-> 이값이 저장될 변수라는것
(실제로 내가 사용할 데이터가 몇개인지 알 수 있음)

  • 배열의 초기값 : null값


    4byte읽으라고 해서 abcd읽음
    그다음 4byte읽으라고하면) 기존 abcd덮어쓰기함
    -> xyzz 덮어씀-> abcd 덮어쓰고 그다음에 읽으라고 하면 123 쓰고 마지막 d

몇개를 읽을지 처리하는게 read 바이트임


-> 결론) 원래 데이터랑 다른 데이터를 읽는것처럼 읽게됨
(※실제로 읽어들이는 바이트수가 따로 저장되어야함)

-> 파라미터가 byte[] 배열인 메소드로 바꿈


(저장하는 장소, 실제 반환하는게 다르게 되어있음)


-> 바이트 배열에 저장하고 4가 넘어감
읽어들인건 b에 있고 readByte에는 4가들어감

b배열의 모든 데이터를 추가함x

b배열의 read


-> byte배열의 내용을 string으로 바꾸고, offset(index 0지정할 예정), length(몇글자를 반환하겠다)
-> length (몇글자) : readbyte
-> 읽어들인 글자수 만큼만 반환


-> 4번 반복하겠다
-> 반복문으로


4바이트 준비했다고 언제나 4바이트를 다쓰면 안된다(읽어들인 데이터는 다를 수 있음)

*깨진이유?
한글 : 3byte임
한번에 4개씩 읽음-> 안되는이유

(결론) 한글파일은 못읽음


-> 3으로 되는건 ) 어쩌다 되는것

영어는 1byte가 1글자라서 4byte읽을때 4글자읽음

한번에 여러개 읽는게 빠름


업로드중..
-> 읽어들일 [숫자] 팍팍 줘도 됨
-> 한글 외 파일은 이걸로 사용가능!

★★★ex03()_BufferedInputStream(가장성능이 우수함) - 애초에 stream에 buffer쓰고 읽어들일때 byte배열씀(buffer를 2개 씀) : byte배열이라면 계속 3번으로 읽기!

업로드중..
업로드중..

ex 2번에 buffer까지 끼워서 성능향상시킬

업로드중..
bin(buffered in)

업로드중..
업로드중..
업로드중..
업로드중..
업로드중..
업로드중..

profile
개발자 velog

0개의 댓글