Java OutputStream 가이드

1. 개요

이 자습서에서는 Java 클래스 OutputStream 에 대한 세부 정보를 살펴 봅니다 . O utputStream 은 추상 클래스입니다. 이것은 바이트의 출력 스트림을 나타내는 모든 클래스의 수퍼 클래스 역할을 합니다.

"출력"및 "스트림"과 같은 이러한 단어의 의미를 자세히 살펴 보겠습니다.

2. Java IO에 대한 간략한 소개

OutputStream은 Java 에서 I / O 작업을 수행하는 데 필요한 클래스를 정의 하는 Java IO API의 일부입니다 . 이들은 모두 java.io 네임 스페이스에 패키지되어 있습니다. 이것은 버전 1.0부터 Java에서 사용할 수있는 핵심 패키지 중 하나입니다.

Java 1.4부터는 non-blocking 입력 및 출력 작업을 가능하게하는 java.nio 네임 스페이스에 패키지 된 Java NIO도 있습니다 . 그러나이 기사의 초점 영역 은 Java IO의 일부인 ObjectStream 입니다.

Java IO 및 Java NIO와 관련된 세부 정보는 여기에서 확인할 수 있습니다.

2.1. 입력과 출력

Java IO는 기본적으로 소스에서 데이터를 읽고 대상에 데이터를 쓰는 메커니즘을 제공 합니다 . 입력은 소스를 나타내고 출력은 여기에서 대상을 나타냅니다.

이러한 소스 및 대상은 파일, 파이프에서 네트워크 연결에 이르기까지 무엇이든 될 수 있습니다.

2.2. 스트림

Java IO는 기본적으로 연속적인 데이터 흐름을 나타내는 스트림 개념을 제공합니다 . 스트림은 바이트, 문자, 객체 등과 같은 다양한 유형의 데이터를 지원할 수 있습니다.

또한 소스 또는 대상에 대한 연결은 스트림이 나타내는 것입니다. 따라서 이들은 각각 InputStream 또는 OutputStream으로 제공 됩니다.

3. OutputStream 인터페이스

OutputStream 은 하위 클래스에 몇 가지 고유 한 문자를 제공하는 일련의 인터페이스를 구현합니다. 빨리 살펴 보겠습니다.

3.1. 폐쇄 가능

Closeable 인터페이스 는 데이터의 소스 또는 대상 닫기처리 하는 close () 라는 메서드를 제공합니다 . OutputStream의 모든 구현은 이 메서드의 구현을 제공해야합니다. 여기에서 리소스를 해제하는 작업을 수행 할 수 있습니다.

3.2. AutoCloseable

AutoCloseable 인터페이스 는 또한 Closeable 의 것과 유사한 동작을 가진 close () 라는 메서드를 제공합니다 . 그러나이 경우 try-with-resource 블록을 종료 할 때 close () 메서드 가 자동으로 호출됩니다.

try-with-resource에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

3.3. 세척 가능

Flushable 인터페이스 는 대상에 대한 데이터 플러시를 처리하는 flush () 라는 메서드를 제공 합니다.

OutputStream 의 특정 구현은 최적화를 위해 이전에 쓴 바이트를 버퍼링하도록 선택할 수 있지만 flush ()를 호출 하면 대상에 즉시 기록됩니다 .

4. OutputStream의 메소드

OutputStream 에는 각 구현 클래스가 각각의 데이터 유형에 대해 구현 해야하는 여러 메서드가 있습니다.

이는 CloseableFlushable 인터페이스 에서 상속 되는 close ()flush () 메서드 와는 다릅니다 .

4.1. 쓰기 (int b)

이 메서드를 사용하여 특정 바이트를 OutputStream 수 있습니다 . 인수 "int"는 4 바이트로 구성되기 때문에 계약과 마찬가지로 첫 번째 하위 바이트 만 기록되고 나머지 세 개의 상위 바이트는 무시됩니다.

public static void fileOutputStreamByteSingle(String file, String data) throws IOException { byte[] bytes = data.getBytes(); try (OutputStream out = new FileOutputStream(file)) { out.write(bytes[6]); } }

데이터와 함께이 메서드를 "Hello World!"로 호출하면 결과적으로 다음 텍스트가있는 파일이 생성됩니다.

W

우리가 볼 수 있듯이 이것은 여섯 번째로 색인 된 문자열의 일곱 번째 문자입니다.

4.2. write (byte [] b, int off, int 길이)

이 오버로드 된 write () 메서드 버전은 바이트 배열의 하위 시퀀스를 OutputStream에 기록합니다 .

OutputStream 에 "off"로 결정된 오프셋에서 시작하는 인수에 지정된대로 바이트 배열에서 "length"바이트 수를 쓸 수 있습니다 .

public static void fileOutputStreamByteSubSequence( String file, String data) throws IOException { byte[] bytes = data.getBytes(); try (OutputStream out = new FileOutputStream(file)) { out.write(bytes, 6, 5); } }

이제 이전과 동일한 데이터로이 메서드를 호출하면 출력 파일에 다음 텍스트가 표시됩니다.

World

이것은 인덱스 5에서 시작하여 5 개의 문자로 구성된 데이터의 하위 문자열입니다.

4.3. 쓰기 (바이트 [] b)

이것은 OutputStream 에 대한 인수에 의해 지정된대로 전체 바이트 배열 수 있는 write () 메서드 의 또 다른 오버로드 된 버전입니다 .

이것은 write (b, 0, b.lengh) 호출과 동일한 효과를 갖습니다 .

public static void fileOutputStreamByteSequence(String file, String data) throws IOException { byte[] bytes = data.getBytes(); try (OutputStream out = new FileOutputStream(file)) { out.write(bytes); } }

이제 동일한 데이터로이 메서드를 호출하면 출력 파일에 전체 문자열 이 있습니다.

Hello World!

5. Direct Subclasses of OutputStream

Now we'll discuss some of the direct known subclasses of OutputStream which individually represent a specific data type of which the OutputStream they define.

They define their own methods apart from implementing those inherited from OutputStream.

We won't go into the details of these subclasses.

5.1. FileOutputStream

As the name suggests, a FileOutputStream is an OutputStream to write data to a File. FileOutputStream, like any other OutputStream, can write a stream of raw bytes.

We have already examined different methods in FileOutputStream as part of the last section.

5.2. ByteArrayOutputStream

ByteArrayOutputStream is an implementation of OutputStream that can write data into a byte array. The buffer keeps growing as ByteArrayOutputStream writes data to it.

We can keep the default initial size of the buffer as 32 bytes or set a specific size using one of the constructors available.

The important thing to note here is that the method close() has practically no effect. The other methods in ByteArrayOutputStream can be safely called even after close() has been called.

5.3. FilterOutputStream

OutputStream primarily writes a byte stream to a destination, but it can as well transform the data before doing so. FilterOutputStream represents superclass of all such classes which perform a specific data transformation. FilterOutputStream is always constructed with an existing OutputStream.

Some of the examples of FilterOutputStream are BufferedOutputStream, CheckedOutputStream, CipherOutputStream, DataOutputStream, DeflaterOutputStream, DigestOutputStream, InflaterOutputStream, PrintStream.

5.4. ObjectOutputStream

ObjectOutputStream can write primitive data types and graphs of Java objects to a destination. We can construct an ObjectOutputStream using an existing OutputStream to write to a specific destination like File.

Please note that it is necessary for objects to implement Serializable for ObjectOutputStream to write them to a destination. You can find more details on Java Serialization here.

5.5. PipedOutputStream

A PipedOutputStream is useful to create a communication pipe. PipedOutputStream can write data which a connected PipedInputStream can read.

PipedOutputStream features a constructor to connect it with a PipedInputStream. Alternatively, we can do this later by using a method provided in PipedOutputStream called connect().

6. OutputStream Buffering

Input and output operations typically involve relatively expensive operations like disk access, network activity, etc. Performing this often can make a program less efficient.

We have “buffered streams” of data in Java to handle these scenarios. BufferedOutputStreamwrites data to a buffer instead which is flushed to the destination less often, when the buffer gets full, or the method flush() is called.

BufferedOutputStream extends FilterOutputStream discussed earlier and wraps an existing OutputStream to write to a destination:

public static void bufferedOutputStream( String file, String ...data) throws IOException { try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { for(String s : data) { out.write(s.getBytes()); out.write(" ".getBytes()); } } }

The critical point to note is that every call to write() for each data argument only writes to the buffer and does not result in a potentially expensive call to the File.

In the case above, if we call this method with data as “Hello”, “World!”, this will only result in data being written to the File when the code exits from the try-with-resources block which calls the method close() on the BufferedOutputStream.

This results in an output file with the following text:

Hello World!

7. Writing Text with OutputStreamWriter

A byte stream, as discussed earlier, represents raw data which may be a bunch of text characters. Now we can get the character array and perform the conversion to the byte array ourselves:

byte[] bytes = data.getBytes();

Java provides convenient classes to bridge this gap. For the case of OutputStream, this class is OutputStreamWriter. OutputStreamWriter wraps an OutputStream and can directly write characters to the desired destination.

We can also optionally provide the OutputStreamWriter with a character set for encoding:

public static void outputStreamWriter(String file, String data) throws IOException { try (OutputStream out = new FileOutputStream(file); Writer writer = new OutputStreamWriter(out,"UTF-8")) { writer.write(data); } }

이제 볼 수 있듯이 FileOutputStream 을 사용하기 전에 문자 배열을 바이트 배열로 변환 할 필요가 없습니다 . OutputStreamWriter 는이 작업을 편리하게 수행합니다 .

"Hello World!"와 같은 데이터로 위의 메서드를 호출하면 당연히 다음과 같은 텍스트가있는 파일이 생성됩니다.

Hello World!

8. 결론

이 기사에서는 Java 추상 클래스 OutputStream에 대해 설명했습니다 . 우리는 그것이 구현하는 인터페이스와 제공하는 방법을 살펴 보았습니다.

그런 다음 Java에서 사용할 수있는 OutputStream 의 일부 하위 클래스에 대해 논의했습니다 . 마침내 버퍼링과 문자 스트림에 대해 이야기했습니다.

항상 그렇듯이 예제 코드는 GitHub에서 사용할 수 있습니다.