JAVA

[JAVA] IO

sian han 2022. 4. 13. 18:45

https://scshim.tistory.com/283A

 = 정리하고도 완벽하게 이해가 되지 않아서 여러 웹사이트를 찾아봤는데 개중 가장 잘 정리해둔 사이트.

    추후에 또 헷갈리면 여기들어가서 먼저 보고, 내 정리 보기

 

 

 

 

자바에서의 입출력(I/O)

 

▶ 입출력

  - 입출력은 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고 받는 것

     ex ) 키보드로부터 데이터를 입력 받는다거나 System.out.println() 을 이용해서 화면(모니터)에 출력한다거나 하는 것

 

 

※ 스트림

  - 어느 한쪽에서 다른 쪽으로 데 이터를 전달하려면, 두 대상을 연결하고 데이터를 전송할 수 있는 무언가가 필요한데      이것을 스트림이라고 함

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

  - 단방향 통신만 가능하다 

    따라서 입력과 출력을 동시에 수행하려면 입력을 위한 입력스트림과

    출력을 위한 출력스트림 총 2개의 스트림이 필요하다.

 

▶ Stream 구분

 

[1] 스트림에서 다루는 데이터에 따른 구분

 

  ▷ 바이트 기반 스트림 : 1byte (8bit) 단위로 데이터를 이동시킨다

        - ~InputStream/~OutputStream : InputStream/OutputStream = 바이트 기반 스트림의 조상

        - 스트림은 바이트 단위로 데이터를 전송하며 입출력 대상에 따라 다음과 같은 입출력 스트림이 있다

입력스트림 출력스트림 입출력 대상의 종류
FileInputStream FileOutputStream 파일
ByteArrayInputStream ByteArrayOutputStream ByteArrayOutputStream

ex ) 파일의 내용을 읽겠다 ! FileInputStream 사용

 

 

 

▶ InputStream 

 

▷ read()

public int read() throws IOException

FileInputStream fis = new FileInputStream("test.txt"); //기본 스트림을 생성한다
fis.read()  //기본스트림으로 부터 데이터를 읽는다

- Reads a byte of data from this input stream

- inputStream에서 1바이트씩 읽어온다.

   2바이트 한글은 쪼개서 출력되기때문에 오류난다

- 아스키코드를 리턴함

- 더 이상 읽어올 것이 없으면 -1을 리턴함 (-1을 제외하고는 0~255 범위(1byte) 의 정수값 리턴)

- int 로 반환값 받아주고 char 로 자료형바꿔주면 자료를 읽을 수 있다

 

▷ read(byte[] b) : 배열 b의 크기만큼 읽어서 배열을 채우고 읽어 온 데이터의 수를 반 환함

 

 

▶ OutputStream

 

▷ void close() : 입력 소스를 닫음으로써 사용하고 있던 자원을 반환한다

      - 스트림을 사용 해서 모든 작업을 마치고 난 후에는 close()를 호출해 서 반드시 닫아 주어야 함

      - 왜냐면 버퍼는 공간이 꽉차야 출력을 하는데, 따라서 마지막에 버퍼에 남아있는 데이터는 출력이 안될수도 있다

 void flush() : 스트림의 버퍼에 있는 모든 내용을 출력 소스에 쓴다

      - 버퍼가 있는 출력 스트림의 경우에만 의미가 있으며, OutputStream에 정의된 flush()는 아무런 일도 하지 않음

 void write(int b) : 주어진 값을 출력소스에 쓴다.

 void write(byte[] b) : 주어진 배열 b에 저장된 모든 내용을 출력소스에 쓴다.

byte[] buf=new byte[1024];
//int read(byte[] b)
/* 	-InputStream에서 읽어서 byte배열에 넣는다(byte배열의 길이만큼)
    -읽어온 개수를 리턴함
 */
while((cnt=fis.read(buf))!=-1) {
    System.out.write(buf, 0, cnt);
    //void write(byte[] b, int off, int len)
    //=>buf 배열에서 0부터 cnt개 읽어서 출력소스에 쓴다
    fos.write(buf,0,cnt);

    System.out.println("\n-------------cnt : " + cnt+"\n");
    total+=cnt;  //1024+1009
    count++; //1,2
}

 

 

 

   문자(char) 기반 스트림 : 2byte 단위로 문자(데이터)가 이동한다

        - ~Reader/~Writer

        - java에서는 한문자를 의미하는 char 형이 2byte이기 때문에

          바이트 기반의 스트림으로는 2byte인 문자를 처리 하는데 어려움이 있다

          따라서 문자 데이터를 입출력할 때는 바이트 기반 스트림 대신 문자 기반 스트림을 사용

 

InputStream => Reader

OutputStream => Writer

 

Reader/ Writer : 문자기반의 스트림의 조상

 

FileReader/FileWriter : 파일로부터 텍스트 데이터를 읽고, 파일에 쓰는 데 사용

public class ReaderTest1 {

	public static void main(String[] args) {
		String fileName="text/test.txt";
		FileInputStream fis=null; 
        
        int data=0;
        
        try {
			fr=new FileReader(fileName); //file reader로 한문자씩 읽어서 (문자기반)
			while((data=fr.read())!=-1) { // int data 에 넣음 (문자단위로 읽는다 = 2바이트씩 읽음)
				System.out.print((char)data); // int => char 로 변환해서 찍음
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(fr!=null)fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

 

 

 

 

 

[2] 스트림안에 들어온 데이터를 그대로 보내느냐, or

     가공절차를 거친 뒤 보내느냐에 따른 구분

 

  Node 스트림 : 데이터 소스와 직접 연결 가능한 스트림

 

  보조 스트림

    : 스트림의 기능을 보완하기 위한 보조 스트림 => 노드 스트림과 연결해서 써야 함.

      - 데이터 소스에 직접 연결은 불가능하고, 데이터 소스에 직접 연결한 노드 스트림을 가공하는 역할을 하는 스트림

      - 스트림을 먼저 생 성한 다음에 이를 이용해서 보조스트림을 생성해야 함

 

 

 ex ) test.txt 파일을 읽기 위해 FileInputStream 을 사용할 때,

       입력 성능을 향상시키기 위해 버퍼를 사용하는 보조 스트림인 BufferedInputStream을 사용하는 코드

FileInputStream fis = new FileInputStream("test.txt"); // 먼저 기본 스트림을 생성한다
BufferedInputStream bis = new BufferedInputStream(fis); //기본 스트림을 이용해서 보조 스트림을 생성한다
bis.read(); // //기본 스트림을 이용해서 보조 스트림을 생성한다

  = > 실제 입력기능은 BufferedInputStream과 연결된 FileInputStream이 수행,

        보조 스트림인 BufferedInputStream은 버퍼만을 제공

입력 출력 설명
BufferedInputStream BufferedOutputStream 버퍼를 이용한 입출력 성능 향상
DataInputStream DataOutputStream int, float와 같은 기본형 단위로 데이 터를 처리하는기능
ObjectInputStream ObjectOutputStream 데이터를 객체 단위로 읽고 쓰는데 사용. 주로 파일을 이용하며 객체 직 렬화와 관련 있음

 

FilterInputStream과 FilterOutputStream : InputStream/ OutputStream 의 자손이면서 모든 보조 스트림의 조상

 

BufferedInputStream과 BufferedOutputStream :

한 바이트씩 입출력하는것 보다는 버퍼(바이트 배열)를 이용해서

한 번 에 여러 바이트를 입출력하는 것이 빠르기 때문에 대부분의 입출력 작업 에 사용됨

 

▷ BufferedInputStream 입력작업 순서 :

1. read 메서드 호출
2. ★ read 메서드가 (1.버퍼크기만큼 데이터를 읽어서 내부버퍼에저장 2. 1byte 씩 데이터를 읽음) 을 처리한다

3. 이제 프로그램에서는 BufferedInputStream의 버퍼에 저장된 데이터를 읽는다

  = > 외부의 입력소스로부터 읽는 것보다 내부의 버퍼로부터 읽는 것이 훨씬 빠르기 때문에 그만큼 작업 효율이 높아진다

 

▽ 생성자

BufferedInputStream(InputStream in, int size)
// BufferedInputStream의 버퍼크기는 입력소스로부터 한 번에 가져올 수
있는 데이터의 크기로 지정하면 좋다 // file의 경우 : 512, 1024, 2048 정도의 크기

BufferedInputStream(InputStream in) // 버퍼의 크기를 지정해 주지 않으므로
기본적으로 2048byte 크기의 버퍼를 갖게 됨

 

▷ BufferedOutputStream 입력작업 순서

1. 프로그램에서 write 메서 드를 이용한 출력이 BufferedOutputStream의 버퍼에 저장

2. 버퍼가 가득 차면, 그 때 버퍼의 모든 내용을 출력소스에 출력

 

 

 

 

 

DataInputStream과 DataOutputStream

: 데이터를 읽고 쓰는데 있어서 byte 단위가 아닌, 8가지 기본 자료형 의 단위로 읽고 쓸 수 있다

    - DataOutputStream이 출력하는 형식은 각 기본 자료형 값을 16진 수로 표현하여 저장함

       ex ) int 값을 출력한다면, 4byte의 16진수로 출력됨

 

 

BufferedReader/ BufferedWriter 

 : 문자 기반의 보조 스트림

- readLine() : BufferedReader의 readLine() 을 사용하면 데이터를 라 인단위로 읽어 올 수 있다

  - newLine() : BufferedWriter의 newLine() - 줄바꿈 해주는 메서드

 

 

InputStreamReader : 바이트기반을 문자기반으로 바꿔줌

 + buffred 사용해서 보조해줘야함

 

 

 

 

 

 

 

 

 

'JAVA' 카테고리의 다른 글

[JAVA] 네트워킹 NetWorking  (0) 2022.04.17
[JAVA] Thread 스레드  (0) 2022.04.14
[JAVA] GUI / 계속 추가예정  (0) 2022.04.11
[JAVA] AWT.EVENT  (0) 2022.04.06
[JAVA] AWT  (0) 2022.04.05