Location>code7788 >text

Java IO Streams Explained

Popularity:438 ℃/2024-08-10 20:03:58

summarize

Streaming is an abstract concept that represents the unstructured transfer of data. The essence of a stream is the transfer of data between different devices. In Java, data is read and written in streams

In Java, streams can be categorized into Input streams and Output streams based on the direction of data flow. Depending on the unit, streams can be categorized into byte streams and character streams. Depending on the level, streams can be categorized into node streams and processing streams.


Input and output streams

Input streams are used to feed data from external devices such as consoles, files, networks, etc. into the application process

Output streams are used to output data from an application process to a console, file, monitor, etc.


Byte Streams and Character Streams

Byte Stream: Byte Stream is to read and write data in units of byte (1byte=8bit), that is to say, byte stream is read or written in units of 8bit, so it is mainly used to deal with binary data. In Java, InputStream and OutputStream are used to process byte data, where InputStream is used for byte stream input and OutputStream is used for byte stream output.

Character Streams: Character streams read and write data in units of characters, a read or write is done in units of 16bit.Characters in Java are encoded in Unicode, and a character occupies 2 bytes. Character streams are mainly used for reading and writing text data, and in the process they need to be converted into character sets. In Java, character data is processed using Reader and Writer, where Reader is used for character stream input and Writer is used for character stream output.

InputStream Byte input stream is an abstract class whose subclasses include:

  • FileInputStream
  • ObjectInputStream
  • ByteArrayInputStream
  • PipedInputStream
  • FilterInputStream
    • BufferedInputStream
    • PushbackInputStream
    • DataInputStream
  • SequenceInputStream
  • StringBufferedInputStream

All methods of the InputStream class throw an IOExcepiion exception when an error is encountered.InputStream is used to read data into an application in the form of bytes, and the commonly used methods and their roles are shown in the following table

methodologies corresponds English -ity, -ism, -ization
int read() Reads 8 bytes of data from the input stream and converts it to an integer from 0-255, the return value is the total number of bytes read, and -1 if it encounters the end of the data stream.
int read(byte[] b) Read the maximum length of len bytes of data from the input stream and save it to the b-byte array, and return -1 if it encounters the end of the data stream.
int read(byte[] b, int off, int len) Read the data with the maximum length of len bytes with the off position in the input stream as the start position, and save it into the b-byte array
void close() Closing the input stream
int available() Returns the number of bits that can be read from the input stream
skip(long n) Skip n bytes from input stream

A piece of code that reads a file based on FileInputStream looks like this:

public static void main(string[] args) throws IoException {
  String path = "file_dir/";
  String fileName = "";
  // 1: Define the file to be read
  File file = new File(path, fileName); // 1:Define the file to be read.
  // 2: Read the data from the file into the FileInputStream.
  FileInputStream fileInputStream = new FileInputStream(file); // 2:Read data from the file into the FileInputStream.
  
  byte[] bytes = new byte[()]; int n = 0;
  // 3: Loop through the bytes from the FileInputStream and write bytes until you reach the end of the stream.
  while ((n = (bytes)) ! = -1) {
    // 4: Converting byte[] to String
    String s = new String(bytes); (s); (n = (bytes) !
    (s);
  }
  // 5:Close the input file stream
  (); }
}

OutputStream A byte output stream is an abstract class whose subclasses include:

  • FileOutputStream
  • ByteArrayOutputStream
  • FilterOutputStream
    • BufferedOutputStream
    • DataOutputStream
    • PrintOutputStream
  • ObjectOutputStream
  • PipedOutputStream

All methods of the OutputStream class throw an IOException when an error is encountered.OutputStream is used to output data to the target device in the form of bytes, and the commonly used methods and their roles are shown in the following table

methodologies corresponds English -ity, -ism, -ization
int write() Write the specified bytes of data to the output stream
int write(byte[] b) Writes the contents of the specified byte array to the output stream
int write(byte[] b, int off, int len) Writes the contents of the specified byte array in len bytes from the off position to the output stream.
close() Closing the data stream
flush() Flushes the output stream, forcing the contents of the buffer to be written to the output stream

A piece of code to read a file based on FileOutputStream is as follows

public static void main(String[] args) throws IOException {
  String path = "file_dir/";
  String fileName = "";
  // 1:Define the file to be written
  File file = new File(path, fileName);
  // 2:defineFileOutputStream
  FileOutputStream fileOutputStream = new FileOutputStream(file, false);
  // 3:Write data toFileOutputStream
  ("hello FileOutputStream new " .getBytes());
  // 4:clotureFileOutputStream
  ();
}

The Reader class is the parent class of all character stream input classes used to read data into an application in character form, and its subclasses include:

  • CharArrayReader: Converts a character array into a character input stream and reads characters from it.
  • StringReader: Converts a string into a character input stream and reads characters from it.
  • BufferedReader: provides read buffers for other character input streams
  • PipedReader: connects to a PipedWriter.
  • FilterReader: subclass of Reader class, used to enrich the functions of Reader class.
  • InputStreamReader: convert byte input stream to character input stream, can specify character encoding

The common methods of the Reader class are as follows

methodologies corresponds English -ity, -ism, -ization
int read() Reads a character from the input stream and converts it to an integer of 0-65535, returning -1 when the end of the stream is reached.
int read(char[] buf) Reads a number of characters from the input stream and saves them in the character array specified by buf, and returns -1 when the end of the stream is reached.
int read(char[] buf, int off, int len) Read the maximum length of len bytes of data and save it to the buf character array starting from the off position in the input stream, and return -1 when the end of the stream is reached.

A piece of code to read a file based on BufferedReader is as follows:

public static void main(string[] args) throws Exception {
  String path = "file_dir.mov";
  //1:Create FileReader
  FileReader fileReader = new FileReader(path); //1:Create FileReader based on FileReader.
  //2:Create BufferedReader based on FileReader
  BufferedReader bufferedReader = new BufferedReader(fileReader);; //3:Define a BufferedReader based on FileReader.
  //3:Define a strLine that represents the result read by BufferedReader
  String strLine = "";
  ///4:Call the readLine method to read the data in the buffer as a string
  //When readLine returns -1, it means it has been read to the end of the file
  while((strLine = ()) ! = null) {
    (strLine);
  }
  //5: Close the fileReader.
  (); }
  //6:Close bufferedReader
  (); }
}

The Writer class is the parent class of all character stream output classes used to write out data in character form to external devices, and its subclasses include:

  • CharArrayWriter: Used to write data to an array of characters in a memory buffer.
  • StringWriter: used to write data to the memory buffer string (StringBuffer)
  • BufferedWriter: used to provide write buffers for other character output streams
  • PipedWriter: Used to connect to a PipedReader.
  • OutputStreamReader: used to convert byte output stream to character output stream, can specify the character encoding
  • FilterWriter: filter character output streams

The common methods of the Writer class are as follows

methodologies corresponds English -ity, -ism, -ization
void write(int c) Write a character to the output stream
void write(char[] cbuf) Write the characters in the character array cbuf to the output stream
void write(char[] cbuf,int off, int len) Writes a character array cbuf of length len from the off position to the output stream.
void write(String str) Write string to output stream
void write(String str,int off, int len) Write part of a string to the output stream
append(char c) Append character c to the output stream
append(charSequence csq) Appends the sequence of characters specified by the csq parameter to the output stream.
append(charSequence csq, int start, int end) Appends a subsequence of the character sequence specified by csq to the output stream.

A piece of code that writes a string to a file based on BufferedWriter is as follows:

public static void main(String[] args) throws Exception {
  //1:Define aFileWriter
  String path = "";
  FileWriter writer = new FileWriter(path);
  //2:on the basis ofFileWriterDefine aBufferWriter
  BufferedWriter bufferedWriter = new BufferedWriter(writer)
  //3:call (programming)BufferedWriter(used form a nominal expression)writemethod writes the string to theBufferedWriter
  ("write by str");
  //4:clotureBufferedWriter
  ();
  //5:clotureFileWriter
  ();
}

Node flow and processing flow

Node streams are low-level streams that are directly connected to a data source and read and write to streams on the data source.

Processing streams are high-level streams that use the modifier pattern to encapsulate the node streams, which are not directly connected to the data source, and are mainly used to eliminate the differences in the implementation of different node streams, and to provide a more convenient way to complete the input and output of data.

For example, FileInputStream, FileOutputStream, FileReader, FileWriter belong to node streams; BufferInputStream, BufferOutputStream, BufferReader, BufferWriter belong to processing streams. The

As opposed to node streams, processing streams have the following properties:

  • High performance: The processing stream improves the efficiency of data input and output by increasing the cache.
  • Ease of operation: Processing streams encapsulate a series of high-level methods to accomplish the input and output of large quantities of data at one time.

memory-mapped file technology

The operating system can utilize virtual memory to "map" a file or part of a file into memory. The file can then be accessed as memory data, much faster than a traditional file, using memory-mapped file technology.

A key advantage of memory-mapped file technology is that the operating system takes care of the actual file reads and writes, and the application program only has to deal with the memory data, allowing for very fast IO operations. During the write process, even if the application exits with a process error after writing the data to memory, the operating system still writes the data in the memory-mapped file to the file system. Another more prominent advantage is shared memory, i.e., the memory mapped file can be accessed by multiple processes at the same time, acting as a low-latency shared memory.

The packages in Java support memory-mapped files, which are used to read and write memory via MappedByteBuffer, and the memory-mapped file technique involves memory outside of Java's heap space, which is one reason for its efficiency.

Mapping and manipulating a file into memory in Java is divided into three steps as follows:

Get a channel from a file.

RandomAccessFile raf = new RandomAccessFile(filePath, "rw");
FileChannel fc= ();

Call the map method of FileChannel to map a file to virtual memory.

MappedByteBuffer buffer = (mode, 0, length);

The mode parameter is used to specify the mapping mode, and the following three modes are supported:

  • .READ_ONLY: the resulting buffer is read-only
  • .READ_WRITE: The resulting buffer is writable and any modifications are written back to the file at some point. Note that other programs mapping the same file may not see these modifications immediately; the final behavior of multiple programs mapping files at the same time is operating system-dependent
  • : the resulting buffer is writable, but any modifications are private to that buffer and are not propagated to the file

Calls the MappedByteBuffer'sput(byte[] src) To write data to a memory-mapped file, call theget(int index) Get the data corresponding to the index in the file and return it in bytes.

public static void main(String[] args) throws Exception {
  //1:Define the file stream
  String path = "file_path/";
  RandomAccessFile raf = new RandomAccessFile(path, "rw");
  //2:Get FileChannel
  FileChannel fc = ();
  ///3:Define the MappedByteBuffer.
  int start = 0.
  int len = 1024;
  //The process of calling the map function is actually the process of mapping disk files to memory data.
  //After calling the map function on a filechannel, the application can use the file as if it were in memory.
  MappedByteBuffer mbb = (, start, len);
  //4:Carry out the input of MappedByteBuffer data, respectively, in the memory mapped file to write the following string
  ("12345".getBytes());
  ("6789".getBytes()).
  mbb,put("wanglei".getBytes());
  //read the ninth character, the result of "w"
  ((char)(9));
  //5: MappedByteBuffer data reading: read all the data
  for (int i = start; i < (); i++) {
    ((char)(i)); }
  }
}