본문 바로가기

IT_Term

[IT_Term] Java.io.Stream_방통대 교재 정리

728x90

###. Java.io.Stream

#. Stream

 - 사전적 의미는 '기체나 액체의 흐름'

 - 데이터 자체를 의미하는 것이 아니라 물이 흐르는 파이프와 같이 데이터가 지나가는 통로를 의미

 -데이터의 생산자(생성지)와 데이터의 소비자(목적지)를 연결하는 통로 역할을 하며, 통과하는 데이터를 처리하거나 제어하는 역할을 할 수 있다.

 

###. 프로그램 관점에서의 Stream

#. 입력 스트림

 - 프로그램이 데이터를 입력받을 때 입력스트림을 사용

 

#. 출력 스트림

 - 프로그램이 데이터를 출력할 때 출력 스트림을 사용

 

#. 스트림의 특성

 - 스트림에 입력된 데이터는 입력된 순서로 데이터 소비자(목적지)에게 전달

 - 데이터 소비자는 스트림을 통해 전달되는 데이터에 순차적으로 접근해야 한다.

 - 다시 말해 특정 데이터만 읽어 오거나 데이터 전달 순서를 무시하면서 데이터에 접근할 수 없다.

 - 하나의 스트림에서 데이터는 항상 정해진 방향으로 전달되며, 도중에 데이터 전달 방향을 바꾸는 것은 불가능하다.

 - 한번 생성된 스트림은 데이터 생산자(소스), 소비자(목적지)의 존재와 상관없이 명시적으로 소멸되기 전까지는 계속 존재한다.

 - 블로킹이라 불리는 지연 현상이 발생할 수 있다.

 - 데이터 생산자가 스트림을 통해 전달한 데이터는 항상 실시간으로 데이터 소비자에게 전달되는 것이 아니라 블로킹이 발생하여 전달이 늦어질 수 있다.

 - 블룅이 발생하면 해당 스레드는 Not Running 상태 (대기상태)로 들어가며 다른 스레드가 CPU자원을 얻어 Running 상태가 된다.

 

###. 스트림 분류

#. 스트림

 - 데이터 흐름의 방향에 따라 입력 스트림과 출력 스트림으로 분류

 - 처리하는 데이터의 단위에 따라 바이트 단위의 바이트스트림과 문자 단위의 캐릭터 스트림으로 분류

 - 가체적으로 입출력 기능을 수행하는 기본 스트림과 입출력 기능을 수행할 수는 없지만 기능을 보완해 주는 역할의 보조스트림

 

#. 입출력 스트림

 - 프로그램의 관점에서 데이터가 소스로부터 프로그램으로 입력되는 용도로 사용되는 것이 입력 스트림

 - 프로그램으로부터 목적지로 데이터가 출력되는 용도로 사용되는 것이 입력 스트림

 - 입력 스트림을 사용하려면 데이터를 읽어 들일 수 있게 데이터 생산자(소스)가 설정 되어야한다.

 - 출력 스트림을 사용하려면 데이터를 출력할 수 있게 데이터 소비자 (목적지)가 설정 되어야 한다.

 

#. 바이트 캐릭터 스트림

 - 스트림을 다루는 데이터의 종류에 따라 바이트 스트림과 캐릭터 스트림으로 구분

 - 바이트 스트림은 바이트 단위로 데이터를 다루는 스트림

 - 캐릭터 스트림은 char형 단위로 데이터를 다루는 스트림

 - 캐릭터 스트림은 모든 문자열을 UNICODE 형태로 변환하여 주고 받게 해줌

 

#. 기본 스트림/ 보조스트림

 - 자체적으로 입출력 기능을 수행할 수는 없지만 기본 입출력 스트림과 함께 사용되어 여러가지 보조 기능을 제공하는 스트림

 

#. 스트림의 분류

 

처리 단위 입력 스트림 출력 스트림
기본스트림 바이트 스트림 InputStream
FileinputStream
OutputStream
FileOutputStream
문자 스트림 Reader
FileReader
Writer
FileWriter
보조 스트림 바이트 스트림 BufferedInputStream
DataInputStream
ObjectInputStream
BufferedOutputStream
PrintStream
DataOutputStream
ObjectOutputStream
문자 스트림 BufferdReader BufferdWriter
PrintWriter
기타 InputStreamReader OutputStreamReader

 

 

#. 스트림 사용하기

 - 스트림을 사용할 때, 즉 데이터 입출력을 할 때는 기본 스트림을 사용

 - 필요에 따라 보조 스트림을 함께 사용

 

#. 일반적으로 어떤 스트림을 사용할 것인지는 다음과 같은 절차에 따라 결정됨

 - 프로그램에서의 용도를 파악하여 입력 용도인지 출력 용도인지 결정.

 - 입력 스트림이라면 데이터를 입력받을 데이터 생산자(소스)를 설정

 - 출력 스트림이라면 출력할 데이터 소비자(목적지)를 설정

  : 예를들어 파일로부터 데이터를 읽어와야 한다면 FileInputStream또는 FileReader 스트림을 사용하고, 파일로부터 데이터를 출력해야 한다면 FileoutputStream 또는 FileWriter 스트림을 사용

 - 입출력 용도가 정해졌으면 다룰 데이터가 바이트 단위인지 문자 단위인지 파악

 : 예를 들어 문서 파일이나 문자 데이터를 다루는 경우라면 캐릭터 스트림을 사용

 - 스트림에서 데이터의 특별한 처리가 필요한지 판단한다. 그렇다면 기본 스트림과 보조 스트림을 할께 사용해야 한다. 이떄 기본 스트림을 보조 스트림이 감싸도록 한다. 즉, 기본 스트림 객체를 먼저 생성하고 그것을 이용하여 보조 스트림 객체를 생성하고 사용한다.

 

 

#. 바이트 스트림

 - 처리단위가 바이트인 스트림

 - 바이트 단위 입력 스트림의 최상위 클래스는 InputStream 클래스

 - 바이트 단위 출력 스트림의 최상위 클래스는 OutputStream 클래스

 

 - 기본 Input스트림 클래스

 : ByreArrayInputStream : 클래스는 byte형 배열로부터 데이터를 바이트 단위로 읽기위한 클래스

 : FileInputStream : 파일로부터 데이터를 byte 단위로 읽기위한 클래스

 

 - Input 보조 클래스 : 직접 데이터 입출력에 관여하지 않으며 기본 스트림 스트림 클래스와 함께 사용되는 클래스

 : FilterInputStream

  ㄴ. BufferedInputStream

  ㄴ. DataInputStream

 : PipedInputStream

 

 - 기본 Output 스트림 클래스

 : ByteArrayOutpuStream

 : FIleOutputStream

 

 - Output 보조 클래스

 : FilterOutputStream

  ㄴ. BufferedOuputStream

  ㄴ. DataOutputStream

 : PipedOuputStream

 

###.InputStream Class

#. InputStream

 - InputStream은 추상 클래스로 실제 프로그래밍에서 InputStream 클래스의 객체를 직접 사용하는 경우는 없다.

 

#. Input Class의 메서드

 - int availavle() : 입력 스트림에서 블로킹 없이 바로 읽어 들일 수 있는 데이터의 길이를 바이트 단위로 리턴

 - void close() : 현재 스트림을 닫고 스트림과 관련된 자원을 스스템에 돌려준다.

 - void mark(int readlimit) : 현재 스트림에서 읽고 있는 위치를 표시

 - boolean markSupported() : 현재 스트림이 mark() 메서드 호출로 표시가 가능한 스트림인지 true, false 반환

 - void reset() : mark()를 호출한 뒤에 사용할 수 있으며 mark()로 표시한 위치로 이동

 - int read(byte[] b, int off, int len) : 입력 스트림으로부터 데이터를 읽어서 byte형 배열 b에 저장하고 읽어드린 바데이터의 바이트 수를 리턴, off는 읽은 데이터를 저장할 배열의 시작위치이고 len은 읽어들일 최대 길이

 - abstarct int read () : 입력 스트림으로부터 다음 바이트를 익어 들인 후 리턴한다.

 

###. OutputStream Class

#. OutputStream method

 - void close() : 출력 스트림을 닫고 할당받은 자원을 시스템에 돌려준다.

 - void flush() : 스트림에 남아있는 데이터를 데이터 소비자에게 강제로 내보낸다.

 - void writre(byte[] w, int off, int len) : byte형 배열 w의 내용을 출력 스트림으로 보낸다. off는 배열 w에서 실제 출력할 내용의 시작 위치를 의미. 즉 write(w)는 write(w,0,w.length)와 같다.

 

###. 캐릭터 스트림

#. Reader / Writer Class

 - 기능이나 사용법이 바이트 스트림과 거의 같다.

 - 단 바이트 스트림과 달리 처리단위가 char형의 문자, 즉 2바이트라는 사실만 다르다.

 - Stream과 같음으로 InputStream을  Reader, OutputStream을 Writer로 바꾸면 된다.

 

###. 파일 입출력

#. java.io package

 - java.io package를 이용하여 파일로부터 데이터를 읽거나 파일로 데이터를 출력하려면 스트림 클래스 뿐만 아니라 파일을 다루는 클래스도 필요

 - FIle클래스로 파일에 대한 기본적인 작업을 하고 FileInputStream과 FileoutputStream 클래스를 이용하여 파일 입출력을 수행

 

#. File Class

 - 파일은 운영체제에서 데이터를 정하는 기본 단위로 사람이 데이터를 다루는 기본 단위이기도 하다.

 - 파일 및 파일과 관련된 여러가지 기능을 지원하기 위한 시스템을 파일 시스템이라고 하는데 파일 시스템은 트리 모양의 계층 구조인 디렉터리와 데이터 저장의 기본단위인 파일로 구성된다.

 - 파일의 위치를 지정하는 문자열을 경로(path)라고 하는데 경로는 디렉토리 이름고 디렉토리를 구분하는 문자인 "/" 유닉스 계열은 \ 로 구성된다.

 -절대경로

 : 파일의 위치를 최상위 디렉토리인 루트부터 순차적으로 표시하는 것

 - 상대 경로

 : 현재 디렉토리를 기준으로 파일의 위치를 표시하는 것

 - 자바에서는 파일 시스템의 기본이 되는 파일 및 경로명 (pathname)ㅇ르 다루기 위해 File Class를 제공.

 

 - File Class의 생성자 : File(String pathname) : pathname 에 지정된 경로명을 갖는 파일이나 디렉토리를 대상으로 하는 객체를 생성

 : File myFile = new File("C:\Users\Administrator\Desktop\");

 

 - File Class가 제공하는 method()

 : boolean exists() : File 객체에 지정된 ㅣ읆의 파일이 존재하는지 알려준다. 존재하면 true 존재 안하면??

 : boolean isDirectory(), isFile() : File 객체에 지정된 이름이 디렉토리인지 파일인지 알려준다

 : String getName(), getPath() : 파일 이름과 전체 경로를 리턴

 : long length(); 파일의 크기를 바이트 단위로 리턴

 : boolean createnewFile() : File 객체에 지정된 파일을 생성시킨다. "생성이 성공하면 true를 리턴하고" 이런 내용은 앞으로 빼도록하겠다.

 : boolean delete() : File 객체에 지정된 파일이나 디렉토리를 삭제

 : boolen mkdir(), mkdirs() : File 클래스 객체를 생성할 때 지정한 경로를 만든다. mkdir은 지정된 경로의 맨 마지막 디렉토리만 생성, mkdirs는 지정된 경로상의 모든 디렉토리를 다 생성

 : String list () : File 객체에 지정된 디렉토리 안에 들어있는 파일ㄷ르의 이름을 문자열 배열로 리턴

 : File[] listFiles[] : 현재 경로에 위치한 파일들을 배열로 리턴한다.

 : String getParent() : 상위 디렉토리 이름을 리턴

 : File getParentFile() : 상위 디렉토리를 가리키는 File 객체를 리턴

 

 

#. FileEx.java(MkdirEx.java)를 메모장에 만들어서 바탕화면에 만들어보기 예제

 

-------------------

import java.io.*;

 

public class MkdirEx{

 public static void main(String args[]){

    File myFile = new File("C:\\abc\\abcd");

    myFile.mkdirs();

}

}

----------

 $. "---"을 제외한 나머지를 복사하여 메모장에 붙여 넣고 저장한다. 그리고 메모장 이름을 MkdirEx.java로 바꾸고 그 .java 파일을 C드라이브에 넣고 c: 주소 창에 cmd를 입력 후 엔터 그리고 javac MkdirEx.java를 입력하고 그다음 java MkdirEx를 입력하면 C드라이브에 adc라는 폴더와 그 안에 abcd라는 폴더가 생긴다.

$. 참고로 위와 같이 boolen, String, long 이 앞에 붙는 이유는 ".(dot)"으로 사용되며 리턴타입을 의미

$. 참고로 Windows 시스템에서 경로명을 문자열로 지정할 때는 \\와 같이 사용해야 한다.

 

###. RandomAccessFile Class

#. 파일에 대해 읽기나 쓰기 연산을 지원하는 클래스로 입출력 스트림을 사용하지 않고 파일의 임의의 위치에서 데이터를 읽거나 쓸수 있다.

#. 이때 읽거나 쓰는 위치를 가리키는 것을 파일 포인터라고 함

#. 읽기 연산을 수행하면 파일 포이너가 가리키는 위치에서부터 바이트단위로 파일의 내용을 읽어 들이고 읽은 바이트 수만큼 파일 포인터가 이동한다.

 

###. FileInputStream Class

#. FileInputStream

 - 파일로부터 데이터를 바이트 단위로 읽어 들이기 위한 입력 스트림

 - 데이터 생산자가 파일인 입력 시스템

 - 바이트 단위로 데이터를 읽어들이는 바이트 스트림이기 때문에 이미지, 오디오, 비디오 파일과 같은 rqw 데이터를 읽어들이는데 유용

 - 따라서 파일로부터 문자열을 읽고 싶으면 이 클래스 대신 뒤에 설명할 FileReader 클래스를사용

 - 소스 코드

File file = new File("c:\\FileInputStreamEx.java");

InputStream is = new FileInputStream(file);

int nData;

nData = is.read ();

while(nData != -1){

System.out.write(nData);

ndata = is.read();

}

is.close();

 

###. System.in / System.out

#. 키보드로 입혈할 때에는 System 클래스의 static 필드인 in을 사용

#. 화면 출력할 때에는 System 클래스의 static 필드인 out을 사용

 

###. 보조스트림

#. 보조스트림이란 데이터 입출력 기능을 직접 수행하는지는 못보지만 데이터 입출력 기능이 있는 기본 스트림의 성능을 높이거나 편의성을 높이는 보조적인 기능을 수행하는 스트림을 말한다.

#. 보조 스트림 클래스들은 자체로는 입출력이 기능이 없기 떄문에 반드시 입출력 기능이 있는 스트림 클래스의 객체를 이용하여 객체를 생성해야 한다.

#. 모든 보조 스트림은 생성자의 매개변수로 기본 스트림 객체를 사용

#. 소스코드

InputStream is = new FileInputStream(infile);

BufferdInputStream is = new BufferedInputStream(is);

 

OutputStream os = new FileOutputStream(outFile);

BufferedOutputStream bos = new BufferedOutputStream(os);

 - 소스에서 보이는 것 처럼 BufferedInputStream 클래스를 사용하려면 InputStream 클래스 중에서 기본 스트림 객체를 생성한 다음 그 것을 생성자의 매개변수로 이용하여 BufferedInputStream 객체를 생성해야 한다. 이것을 '기본스트림을 보조 스트림으로 감싼다'라고 표현한다.

#. 보조스트림을 사용하는 이유

File inFile = new File(C:\\a.java);

File outFile= new File("C:\\b.java");

 Inputstream is = new FileInputStream(inFile);

(Output os)

 BufferdInputStream bis = new BufferedInputStream(is);

bos = out

int nData = bis.read();

while(nData != -1){

bos.write(nData);

}

bis.close();

bos.close();

 - 위 소스와 같이 기능상 달라진 점은 없지만 버퍼링 기능을 추가해서 효율이 더 좋아진다.

 

728x90