Java/라이브스터디

입출력

목표

자바의 Input과 Ontput에 대해 학습하세요.

학습할 것 (필수)

  • 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
  • InputStream과 OutputStream
  • Byte와 Character 스트림
  • 표준 스트림 (System.in, System.out, System.err)
  • 파일 읽고 쓰기

 

 


자바의 입출력

자바에서의 입출력은 Stream, Buffer, Channel 기반으로 작동합니다.

 

스트림( Stream )

스트림(Stream) 이란, 데이터의 흐름 또는 데이터의 순서를 의미합니다.

 

 

Source( 키보드 or 파일 etc.. )에서 InputStream을 이용하여 데이터를 읽어 들이고 OutputStream을 이용하여 Destination( 콘솔 or 파일 etc.. )으로 출력하게 됩니다.

 

Stream은 Queue( 큐 )처럼 작동하기 때문에 단방향이며, 모든 데이터 타입과 기본값, 객체등을 지원합니다.

 

스트림 기반의 패키지는 java.io 패키지입니다.

 

버퍼 ( Buffer )와 채널 ( Channel )

버퍼 ( Buffer )입/출력에 대한 요청들을 저장하는 임시메모리를 의미하며, 이에 저장한 다음 일괄 처리하는 방식으로 작동합니다. 

 

채널 ( Channel )엔티티( ex : 하드웨어, 파일 )와  버퍼 사이의 데이터를 전송하는 데 사용되는 중간 매체를 의미합니다. 엔티티로부터 데이터를 읽어서 버퍼 내로 제공하는 식의 역할을 수행합니다.

 

 

그림에서 볼 수 있 듯이 버퍼와 채널을 이용한 입출력은 양방향으로 동작합니다. 

버퍼 기반의 패키지는  java.nio 패키지입니다.

 

Byte Streams?

InputStream과 OutputStream은 Byte Stream에 해당합니다.

Byte Stream이란, 8비트 ( 1 바이트 )의 입출력을 수행하는 Stream을 의미합니다.


InputStream과 OutputStream

Byte 스트림에서 입출력을 처리하는 데 사용되는 클래스이며 Queue처럼 단방향으로 동작합니다.

 

 

InputStream

Byte 스트림에서 입력을 위하여 사용되는 추상클래스입니다. 

파일, 이미지, 오디오, 피디오 등등을 읽는 데 사용됩니다.

 

java.io.InputStream

 

InputStream (Java Platform SE 8 )

Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is detected, or an exception is thrown. If

docs.oracle.com

하위클래스를 알아보기에 앞서서 해당 클래스의 메소드들을 알아보았습니다.

더보기

 

 

메소드 : available()

    /**
     * Returns an estimate of the number of bytes that can be read (or skipped
     * over) from this input stream without blocking, which may be 0, or 0 when
     * end of stream is detected.  The read might be on the same thread or
     * another thread.  A single read or skip of this many bytes will not block,
     * but may read or skip fewer bytes.
     *
     * <p> Note that while some implementations of {@code InputStream} will
     * return the total number of bytes in the stream, many will not.  It is
     * never correct to use the return value of this method to allocate
     * a buffer intended to hold all data in this stream.
     *
     * <p> A subclass's implementation of this method may choose to throw an
     * {@link IOException} if this input stream has been closed by invoking the
     * {@link #close()} method.
     *
     * <p> The {@code available} method of {@code InputStream} always returns
     * {@code 0}.
     *
     * <p> This method should be overridden by subclasses.
     *
     * @return     an estimate of the number of bytes that can be read (or
     *             skipped over) from this input stream without blocking or
     *             {@code 0} when it reaches the end of the input stream.
     * @exception  IOException if an I/O error occurs.
     */
    public int available() throws IOException {
        return 0;
    }

 

현재 인풋스트림의 앞으로 읽거나 스킵할 수 있는 총 바이트 수를 반환해주는 메소드입니다.

 

대부분의 구현체에서는 총 바이트 수를 반환해주지 않는다고합니다.

그러므로 이 메소드를 이용하여 스트림의 데이터를 보유할 버퍼를 할당하는 것은 올바르지 않습니다.

 

 

 

ex:

public class Learn_InputStream {
    public static void main(String[] args) {

        try(FileInputStream inputStream = new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/FileStream")){
            System.out.println(inputStream.available());
            int item = inputStream.read();
            while(item != -1){
                System.out.print((char)item);
                item = inputStream.read();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
Java_Live
Study
Test

 

available() 출력 값 : 22

 

 

메소드 : close()

    /**
     * Closes this input stream and releases any system resources associated
     * with the stream.
     *
     * <p> The <code>close</code> method of <code>InputStream</code> does
     * nothing.
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void close() throws IOException {}

현재 인풋스트림을 닫고 자원을 반납하는 메소드입니다.

try-with-resource를 사용하면 close를 컴파일 과정에서 달아줍니다.

 

 

메소드 : mark(int readlimit)

   /**
     * Marks the current position in this input stream. A subsequent call to
     * the <code>reset</code> method repositions this stream at the last marked
     * position so that subsequent reads re-read the same bytes.
     *
     * <p> The <code>readlimit</code> arguments tells this input stream to
     * allow that many bytes to be read before the mark position gets
     * invalidated.
     *
     * <p> The general contract of <code>mark</code> is that, if the method
     * <code>markSupported</code> returns <code>true</code>, the stream somehow
     * remembers all the bytes read after the call to <code>mark</code> and
     * stands ready to supply those same bytes again if and whenever the method
     * <code>reset</code> is called.  However, the stream is not required to
     * remember any data at all if more than <code>readlimit</code> bytes are
     * read from the stream before <code>reset</code> is called.
     *
     * <p> Marking a closed stream should not have any effect on the stream.
     *
     * <p> The <code>mark</code> method of <code>InputStream</code> does
     * nothing.
     *
     * @param   readlimit   the maximum limit of bytes that can be read before
     *                      the mark position becomes invalid.
     * @see     java.io.InputStream#reset()
     */
    public synchronized void mark(int readlimit) {}

인풋스트림의 현재위치를 기록합니다. 

markSupported() 메소드를 이용하여 해당 메소드를 지원하는지 여부를 판단할 수 있습니다.

이후 reset() 을 이용하면 기록된 위치에서부터 데이터를 읽어올 수 있습니다.

 

 

메소드 : reset()

    /**
     * Repositions this stream to the position at the time the
     * <code>mark</code> method was last called on this input stream.
     *
     * <p> The general contract of <code>reset</code> is:
     *
     * <ul>
     * <li> If the method <code>markSupported</code> returns
     * <code>true</code>, then:
     *
     *     <ul><li> If the method <code>mark</code> has not been called since
     *     the stream was created, or the number of bytes read from the stream
     *     since <code>mark</code> was last called is larger than the argument
     *     to <code>mark</code> at that last call, then an
     *     <code>IOException</code> might be thrown.
     *
     *     <li> If such an <code>IOException</code> is not thrown, then the
     *     stream is reset to a state such that all the bytes read since the
     *     most recent call to <code>mark</code> (or since the start of the
     *     file, if <code>mark</code> has not been called) will be resupplied
     *     to subsequent callers of the <code>read</code> method, followed by
     *     any bytes that otherwise would have been the next input data as of
     *     the time of the call to <code>reset</code>. </ul>
     *
     * <li> If the method <code>markSupported</code> returns
     * <code>false</code>, then:
     *
     *     <ul><li> The call to <code>reset</code> may throw an
     *     <code>IOException</code>.
     *
     *     <li> If an <code>IOException</code> is not thrown, then the stream
     *     is reset to a fixed state that depends on the particular type of the
     *     input stream and how it was created. The bytes that will be supplied
     *     to subsequent callers of the <code>read</code> method depend on the
     *     particular type of the input stream. </ul></ul>
     *
     * <p>The method <code>reset</code> for class <code>InputStream</code>
     * does nothing except throw an <code>IOException</code>.
     *
     * @exception  IOException  if this stream has not been marked or if the
     *               mark has been invalidated.
     * @see     java.io.InputStream#mark(int)
     * @see     java.io.IOException
     */
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

mark() 와 함께사용 되며, 이후에는 마지막에 기록된 위치에서부터 스트림을 읽어들입니다.

 

 

메소드 : markSupported()

    /**
     * Tests if this input stream supports the <code>mark</code> and
     * <code>reset</code> methods. Whether or not <code>mark</code> and
     * <code>reset</code> are supported is an invariant property of a
     * particular input stream instance. The <code>markSupported</code> method
     * of <code>InputStream</code> returns <code>false</code>.
     *
     * @return  <code>true</code> if this stream instance supports the mark
     *          and reset methods; <code>false</code> otherwise.
     * @see     java.io.InputStream#mark(int)
     * @see     java.io.InputStream#reset()
     */
    public boolean markSupported() {
        return false;
    }

mark()와 reset()을 지원하는지 반환하는 메소드입니다.

해당 메소드가 false를 반환하면 IOException이 발생하고, 해당 메소드들의 사용이 불가능합니다.

true를 반환하더라도 reset() 호출 시, 이전에 mark()를 호출하지 않았거나 스트림의 크기를 넘어서는 위치를 마킹했으면 예외가 발생합니다.

 

 

메소드 : read()

    /**
     * Reads the next byte of data from the input stream. The value byte is
     * returned as an <code>int</code> in the range <code>0</code> to
     * <code>255</code>. If no byte is available because the end of the stream
     * has been reached, the value <code>-1</code> is returned. This method
     * blocks until input data is available, the end of the stream is detected,
     * or an exception is thrown.
     *
     * <p> A subclass must provide an implementation of this method.
     *
     * @return     the next byte of data, or <code>-1</code> if the end of the
     *             stream is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public abstract int read() throws IOException;

인풋스트림의 다음 데이터를 읽는 명령으로, 파라미터를 추가로 사용할 수 있습니다.
스트림의 끝에 다다랐을 때는 -1을 반환합니다.

 

아무런 파라미터를 주지않은 경우 추상메소드이므로 상속하는 클래스에서 구현해주어야 합니다.

 

파라미터를 주는 경우는 두 가지가 존재합니다.

 

  • public int read(byte[] b) throws IOException
    • 파라미터로 주어진 byte배열에 InputStream의 데이터를 저장합니다.
  • public int read(byte[] b, int off, int len) throws IOException
    • byte배열의 off위치부터 데이터를 len만큼 저장합니다.

파라미터가 없는 경우 리턴타입이 int이기 때문에 int형으로 받은다음 형변환을 해주어야하며, 파라미터가 있는 경우에는 읽어들인 길이를 반환합니다.

 

하위 클래스 : FileInputStream

파일경로를 이용하여 해당 파일에서 데이터를 읽어오는데 사용됩니다.

 

package me.ddings73.week13_Java_IO;

import java.io.FileInputStream;
import java.io.IOException;

public class InputStream {
    public static void main(String[] args) {
        try(FileInputStream inputStream = new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/FileStream")){
            int item = inputStream.read();
            while(item != -1){
                System.out.print((char)item);
                item = inputStream.read();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

 

2021/02/06 - [Java/라이브스터디] - 예외 처리에서 배운 try-with-resource 를 이용하여 원하는 파일의 데이터를 읽고 close()는 컴파일러에게 맡기는게 가능합니다.

 

예외 처리

목표 자바의 예외처리에 대해 학습하기 학습할 것 (필수) 자바에서의 예외처리방법(try, catch, throw, throws, finally) 자바가 제공하는 예외 계층 구조 Exception과 Error의 차이는? RuntimeException과 RE가..

ddinsg73.tistory.com

 

 

하위 클래스 : ByteArrayInputStream

package me.ddings73.week13_Java_IO;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Learn_InputStream {
    public static void main(String[] args) {
        try (FileInputStream fileInputStream = new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/FileStream")) {
            byte[] b = new byte[22];
            fileInputStream.read(b);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(b);

            int item = byteArrayInputStream.read();
            while(item != -1){
                System.out.print((char)item);
                item = byteArrayInputStream.read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

내부에 있는 버퍼에 스트림에서 읽어들인 바이트 데이터를 저장하며, 데이터를 읽을 시에 내부에 카운터를 이용하여 읽습니다.

이 클래스의 객체는 close()를 해줘도 효과가 없습니다.

 

 

하위 클래스 : FilterInputStream

생성자의 파라미터로 다른 InputStream를 받아 데이터를 얻습니다.

 

클래스 자체로는 아무런 기능이 없고, 상속하는 클래스를 통하여 사용해야합니다.

 

java.io.FilterInputStream

 

FilterInputStream (Java Platform SE 8 )

Reads up to byte.length bytes of data from this input stream into an array of bytes. This method blocks until some input is available. This method simply performs the call read(b, 0, b.length) and returns the result. It is important that it does not do in.

docs.oracle.com

 

 

하위 클래스 : ObjectInputStream

ObjectOutputStream에 의하여 직렬화된 프리미티브 데이터나 객체를 역직렬화하는 클래스입니다.

 

직렬화란, 자바 내부에서 사용되는 객체나 데이터는 외부의 자바시스템에서 사용될 수 있도록 바이트 형태로 변환하는 기술을 의미합니다.

 

역직렬화란, 바이트로 변환된 데이터를 다시 객체로 변환하는 기술입니다.

 

자바 직렬화

 

자바 직렬화, 그것이 알고싶다. 훑어보기편 - 우아한형제들 기술 블로그

자바의 직렬화 기술에 대한 대한 이야기입니다. 간단한 질문과 답변 형태로 자바 직렬화에 대한 간단한 설명과 직접 프로젝트를 진행하면서 겪은 경험에 대해 이야기해보려 합니다.

woowabros.github.io

 

-> ObjectOutputStream

 

 

하위 클래스 : PipedInputStream

서로다른 Thread간에 데이터를 주고받는데 사용되는 클래스입니다. 

PipedOutputStream과 같이 사용 되어야 합니다.

 

package me.ddings73.week13_Java_IO;

import java.io.*;

public class Learn_InputStream {

    public static void main(String[] args) {
        try {
            PipedOutputStream pipedOutputStream = new PipedOutputStream();
            PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);

            Thread thread01 = new Thread(new Runnable() {
                @Override
                public void run() {
                    String Hello = "Hello Thread02!";
                    try {
                        pipedOutputStream.write(Hello.getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

            Thread thread02 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        int item = pipedInputStream.read();
                        int len = pipedInputStream.available();
                        while(len > 0){
                            len--;
                            System.out.print((char)item);
                            item = pipedInputStream.read();
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

            thread01.start();
            thread02.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 

thread01에서 쓴 데이터를 thread02에서 받아 출력하는 모습을 확인할 수 있습니다.

 

 

하위 클래스 : SequencelInputStream

InputStream간의 논리적 연결을 해주는 클래스입니다. 

둘 이상의 InputStream을 하나의 InputStream으로 다루는 기능을 제공합니다.

 

public class Learn_InputStream {

    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream1 = new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/File01");
        FileInputStream fileInputStream2 = new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/File02");

        SequenceInputStream sequenceInputStream = new SequenceInputStream(fileInputStream1, fileInputStream2);

        int item = sequenceInputStream.read();
        while(item != -1){
            System.out.print((char)item);
            item = sequenceInputStream.read();
        }
    }
}

두 InputStream을 하나의 InputStream으로 모두 호출할 수 있습니다.

 

 

 

 

OutputStream

Byte 스트림에서 출력을 위하여 사용되는 추상클래스입니다.

데이터를 파일이나 이미지, 오디오등에 작성하는데 사용됩니다.

 

 

 

java.io.OutputStream

 

OutputStream (Java Platform SE 8 )

Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such b

docs.oracle.com

 

사용가능한 메소드

더보기

 

메소드 : close()

현재 OutputStream을 닫고 자원을 반환하는 메소드입니다.

 

 

메소드 : flush()

    /**
     * Flushes this output stream and forces any buffered output bytes
     * to be written out. The general contract of <code>flush</code> is
     * that calling it is an indication that, if any bytes previously
     * written have been buffered by the implementation of the output
     * stream, such bytes should immediately be written to their
     * intended destination.
     * <p>
     * If the intended destination of this stream is an abstraction provided by
     * the underlying operating system, for example a file, then flushing the
     * stream guarantees only that bytes previously written to the stream are
     * passed to the operating system for writing; it does not guarantee that
     * they are actually written to a physical device such as a disk drive.
     * <p>
     * The <code>flush</code> method of <code>OutputStream</code> does nothing.
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void flush() throws IOException {
    }

지금까지 write()된 데이터를 즉시 기록합니다.

 

 

메소드 : write()

파라미터로 int 값 또는 byte[] 를 줄 수 있습니다.

i값을 ASCII코드로 변환하여 기록합니다.

 

 

하위 클래스 : ByteArrayOutputStream

byte 배열을 반환하는 메소드입니다.

 

public class Learn_OutputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/File01.txt");

        byte[] from = new byte[20];
        fileInputStream.read(from);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byteArrayOutputStream.write(from);

        byte[] to = byteArrayOutputStream.toByteArray();

        for (byte b : to) {
            System.out.print((char)b);
        }
    }
}

해당 스트림에 byte값을 기록하고 다른 배열에 저장하는게 가능합니다.

 

toString() 을 이용하여 문자열을 반환하는 것도 가능합니다.

 

 

하위 클래스 : FileOutputStream

파일에 데이터를 기록하는 기능을 제공합니다.  

byte값 만을 기록할 수 있으며, 넘어서는 값을 기록하면 문자가 깨집니다.

 

public class Learn_OutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("src/main/java/me/ddings73/week13_Java_IO/File01.txt");
        fileOutputStream.write(127);
        fileOutputStream.write(128);

    }
}

 

 

하위 클래스 : FilterOutputStream

생성자의 파라미터로 다른 OutputStream을 받을 수 있는 클래스들의  상위 클래스입니다.

 

FilterInputStream과 같이 자체로는 별다른 기능이 없고 상속하는 클래스를 이용해야합니다.

 

java.io.FilterOutputStream

 

FilterOutputStream (Java Platform SE 8 )

Writes the specified byte to this output stream. The write method of FilterOutputStream calls the write method of its underlying output stream, that is, it performs out.write(b). Implements the abstract write method of OutputStream.

docs.oracle.com

 

 

하위 클래스 : ObjectOutputStream

 

객체를 직렬화하여 OutputStream에 저장하는 클래스입니다.

 

public class DST implements Serializable {

    public String name;

    private int age;

    public int health;

    public DST(String name, int age, int health) {
        this.name = name;
        this.age = age;
        this.health = health;
    }
}


public class Learn_InputStream {

    public static void main(String[] args) {
        DST me = new DST("Wilson", 30, 150);

        try (FileOutputStream fileOutputStream = new FileOutputStream("src/main/java/me/ddings73/week13_Java_IO/FileStream")){
            ObjectOutputStream objectoutputStream = new ObjectOutputStream(fileOutputStream);
            objectoutputStream.writeObject(me);

            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src/main/java/me/ddings73/week13_Java_IO/FileStream"));
            DST user = (DST)objectInputStream.readObject();
            System.out.println(user.name);

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

 

Serializable 인터페이스를 구현하는 클래스의 객체를 직렬화하는 것이 가능하며, ObjectOutputStream을 사용하여 객체를 저장할 수 있습니다. 

 

 

저장된 파일의 내용

 

ObjectInputStream으로 해당파일을 역직렬화하고, 객체를 반환하여 출력할 수 있습니다.

 



 

 

Character Streams?

Byte Stream의 경우 8비트만 이용하였기 때문에 ASCII 코드를 사용하였던 것에 비하여 Character Stream은 16비트, UNICODE를 사용합니다.

 

문자 스트림은 줄 단위로 읽고 쓰는 것이 가능하며 Reader와 Writer로 구현됩니다.

 

Byte Stream에 비하여 가용 비트수가 늘어나서 더 많은 문자의 표현이 가능합니다.  

즉, 이건 한글을 쓸 수 있습니다!!

 

 

Reader

문자스트림을 읽기위한 추상클래스입니다. 

정의되어있는 메소드는 InputStream과 거의 동일합니다.

 

java.io.Reader

 

Reader (Java Platform SE 8 )

reset public void reset() throws IOException Resets the stream. If the stream has been marked, then attempt to reposition it at the mark. If the stream has not been marked, then attempt to reset it in some way appropriate to the particular stream, for ex

docs.oracle.com

 

 

하위 클래스 : BufferedReader

문자 입력 스트림에서 문자, 배열, 줄을 읽어들이는데 사용되는 클래스입니다.

 

데이터의 중간저장 기능을 수행하는 버퍼에서 데이터를 얻어오는 기능을 가지고 있습니다.

 

버퍼링 없이 작업을 수행하면 매 읽기작업마다 읽기 -> 번역 -> 리턴 의 작업을 수행해야하므로 읽기 작업이 많은 FileReader나 InputStreamReader와 함께 사용하면 효율적입니다.

 

기존의 read()에 readLine() 가 추가되어 줄 단위로 데이터를 읽어들이는게 가능합니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("src/main/java/me/ddings73/week13_Java_IO/File02.txt"));
        String str = br.readLine();
        System.out.println(str);
    }
}

 

 

 

하위 클래스 : CharArrayReader

 

문자열을 읽는 기능을 가지고있습니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        char[] chars = {'이', '거', '쓰', '긴', '하', '나', '?'};
        CharArrayReader charArrayReader = new CharArrayReader(chars);
        while(charArrayReader.ready()){
            System.out.println((char)charArrayReader.read());
        }
    }
}

 

 

 

하위 클래스 : FilterReader

필터링된 문자 스트림을 읽는 데 사용되는 추상클래스입니다.

 

상속하고 있는 클래스로 PushbackReader가 존재합니다.

PushbackReader는 unread()를 사용하여 현재 읽어들일 버퍼의 맨 앞에 데이터를 밀어넣을 수 있습니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        PushbackReader pushbackReader = new PushbackReader(new FileReader("src/main/java/me/ddings73/week13_Java_IO/File02.txt"));

        pushbackReader.unread(74);
        System.out.println((char)pushbackReader.read()); 
        // 74 ( J ) 가 출력 됨
        
        System.out.println((char)pushbackReader.read());

    }
}

 

 

 

 

하위 클래스 : InputStreamReader

바이트 스트림과 문자 스트림 사이의 연결점이 되어주는 클래스입니다.

주어진 charset을 사용하여 바이트를 문자로 디코딩합니다.

 

해당 클래스의 read() 메소드는 내부의 바이트인풋 스트림을 이용하여 데이터를 읽어들입니다.

 

해당 클래스를 상속하는 클래스로 FileReader가 존재합니다.

 

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(System.in);
        System.out.println((char)inputStreamReader.read());
    }
}
public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("src/main/java/me/ddings73/week13_Java_IO/File02.txt");
        System.out.println(fr.read());
    }
}

 

 

 

 

하위 클래스 : PipedReader

 

PipedWriter 와 함께 사용되여 멀티스레드 프로그램에서 스레드간에 데이터를 주고받는데 사용할 수 있습니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        PipedWriter pipedWriter = new PipedWriter();
        PipedReader pipedReader = new PipedReader(pipedWriter);

        Thread A = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    pipedWriter.write("A에서 작성");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread B = new Thread(new Runnable() {
            @Override
            public void run() {
                    try {
                        while(pipedReader.ready()) {
                            System.out.println((char)pipedReader.read());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
        });

        A.start();
        B.start();
    }
}

 

 

 

하위 클래스 : StringReader

 

문자열에서 데이터를 읽어들입니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        String str = "Hello?";
        StringReader stringReader = new StringReader(str);

        int c = stringReader.read();
        while(c != -1){
            System.out.println((char)c);
            c = stringReader.read();
        }
    }
}

 

 

 

 

 

Writer

 

Writer의 경우, 버퍼에 데이터를 기록합니다.

따라서 write()만 해서는 버퍼에만 기록되기 때문에 출력되지 않고 반드시 flush()를 해 주어야 정상적으로 출력됩니다.

 

java.io.Writer

 

Writer (Java Platform SE 8 )

Flushes the stream. If the stream has saved any characters from the various write() methods in a buffer, write them immediately to their intended destination. Then, if that destination is another character or byte stream, flush it. Thus one flush() invocat

docs.oracle.com

 

 

 

하위 클래스 : BufferedWriter

 

문자-출력 스트림에 데이터를 작성하는 클래스로 문자, 배열, 문자열 등을 지원하고있습니다.

 

개행문자말고도 newLine() 이라는 메소드를 통하여 개행을 할 수 있습니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new PrintWriter(System.out));
        bw.write(74);
        bw.append('c');
        bw.flush();
        bw.close();
    }
}



== > Jc

 

 

 

 

하위 클래스 : CharArrayWriter

 

버퍼에 문자열을 저장하고 원하는때에 문자열 또는 문자배열로 반환할 수 있습니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        CharArrayWriter caw = new CharArrayWriter();
        caw.write("문");
        caw.write("자");

        String str = caw.toString();

        System.out.println(str);

        caw.flush();
        caw.close();

    }
}

 

 

 

 

하위 클래스 : FileWriter ( extends OutputStreamWriter )

파일에 데이터를 기록하고 싶을 때 사용되는 클래스입니다.

 

public class Learn_Reader {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("src/main/java/me/ddings73/week13_Java_IO/File03.txt"));
        bw.write("안녕하세요오...?");
        bw.newLine();
        bw.flush();
        bw.close();

    }
}

 

 

 

하위 클래스 : PipedWriter

 

PipedReader와 함께 멀티스레드 환경에서 쓰입니다.

 

 

 

 

하위 클래스 : PrintWriter

PrintStream의 모든 print메소드가 사용가능한 Writer입니다. 

 

public class Learn_Reader {
    public static void main(String[] args) {
        PrintWriter printWriter = new PrintWriter(System.out);

        printWriter.println("String");
        printWriter.println(1);
        printWriter.printf("%s", "문자열");
        printWriter.format("%c", '!');

        printWriter.write("???");

        printWriter.flush();
        printWriter.close();

    }
}

 

 

 

하위 클래스 : StringWriter

 

문자열 버퍼에 출력하는 기능을 맡고있으며 close()를 하지 않아도 됩니다.

 

public class Learn_Reader {
    public static void main(String[] args) {
        StringWriter sw = new StringWriter();
        sw.write(1);
        sw.write('2');
        sw.write("34");
        StringBuffer buffer = sw.getBuffer();

        System.out.println(buffer);

    }
}

 

 

 

 

 

 

 

표준 스트림

자바의 표준 스트림은 java.io.system에 명시되어있습니다.

 

 

System.in

표준 입력 스트림으로 키보드로부터 사용자의 입력을 얻어옵니다.

 

 

 

System.out

표준 출력 스트림으로 흔하게 사용하는 System.out.println과 같은 것이 해당됩니다. 

기본적으로 IDE의 콘솔창에 출력됩니다.

 

java.io.PrintStream

 

PrintStream (Java Platform SE 7 )

Appends a subsequence of the specified character sequence to this output stream. An invocation of this method of the form out.append(csq, start, end) when csq is not null, behaves in exactly the same way as the invocation out.print(csq.subSequence(start, e

docs.oracle.com

 

 

System.err

표준 에러출력 스트림으로 오류메시지를 출력해줍니다.

 

public class Learn_Reader {
    public static void main(String[] args) {
        System.err.println("System.err");
        System.out.println("System.out");
    }
}

 

 

출처

표준스트림

자바 스트림 클래스

자바 튜토리얼

GeeksforGeeks NIO와 IO의 차이점

자바 docs Channel

http://tutorials.jenkov.com/java-io/index.html

InputStream과 OutputStream의 차이점