Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Following on from the previous chapter on multithreading, inheritance, and polymorphism, this chapter only focuses on input and output streams.
-
Basic concepts of data flow
In Java, different types of input and output sources are abstracted into lius, in which input or output data is called data flow and is represented by a unified interface.
A data stream is an ordered collection of bytes with a start and end. Programs can use data streams to receive data from the keyboard or write data to a file.
Data flow is divided into input data flow and output data flow. Input data streams can be read but not written, while output data streams can be written but not read. When reading data from a data stream, a data source must be connected to the data stream.
The java.io report provides four basic abstract classes that represent data streams: InputStream, OutputStream, Reader, and Writer.
-
Input data stream
Input data stream refers to the data stream that can only be read but cannot be written. It is used to input information into the computer.
All input data streams in the java.io package are inherited from the abstract class InputStream, and all methods are implemented, including reading data, marking positions, overwriting read/write Pointers, and fetching data quantities. When reading data from a data stream, a data source must be connected to the data stream.
The main data manipulation methods provided in the input data stream are as follows:
- Int read(): Reads one byte of binary data from the input stream
- Int read(byte []b): Reads multiple bytes into an array, filling the entire array
- Int read(byte[]b, int offf, int len): Reads data of length len from the input stream, places the data from array B starting with the subscript off, and returns the number of bytes read.
- Void close(): Closes the data stream. When an operation on a data stream is completed, it should be closed and resources associated with the data stream released.
- Int available(): Returns the current number of bytes that can be read from the data stream (although the actual read operation may read more bytes than the return value).
- Long skip(long L): the specified number of bytes in the data stream is not read, and the return value represents the actual number of bytes skipped.
Bytes in a data stream are usually read in start-to-end order, with push-back operations if they need to be read in the opposite direction. The following method is used to enter a data stream that supports push-back operations:
- Boolean markSupported(): Tests whether a data stream supports push-back operations. Returns true if a data stream supports the mark() and reset() methods, false otherwise
- Void mark(intMarkArea): Marks the current position of the data stream and marks out a buffer whose size is at least the size of the specified parameter.
- Void reset(): Repositions the data stream to the position where the mark method was last called on the stream.
-
Output data stream
An output data stream is a write-only but unreadable stream used to output data from a computer.
Like input streams, most of the output streams in the java.io package inherit from the abstract OutputStream class and implement all of its methods, which provide support for data output.
The main data operations provided in the output data stream are as follows:
- Void write(int I): Writes byte I to the data stream. It outputs the minimum 8 bits of the read parameter. This method is abstract and needs to be implemented in its output stream subclass before it can be used
- Void write(byte b[]): writes all b.length bytes in array B [] to the data stream
- Void write(byte b[], int off, int len): Writes len bytes from array B [] starting with the subscript OFF to the data stream. Element B [off] is the first byte written to this operation, and b[off + len-1] is the last byte written to this operation.
- Void colose(): It should be closed when the output data stream is finished
- Void flush(): Flushes this output stream and forces all buffered output bytes to be written out.
-
-
Basic seasonal data stream classes
InputStream and OutputStream are both abstract classes. Abstract classes cannot be instantiated, so it is not these two classes that are often used in practical applications, but a series of basic data flow classes. They are subclasses of InputStream and OutputStream, and both implement their parent class methods while defining their own specific functionality.
-
File data stream
File data streams include FileInputStream and FileOutputStream. These two classes are used for I/O processing of files, and their data source or data destination should be files. The provided methods allow you to operate on files on your computer, but the mark() and reset() methods are not supported. When constructing a data stream, the file name can be given directly.
FileInputStream fis = new FileInputStream("myFile"); // Thus, the file myFile is used as the data source for the data flow Copy the code
You can also output bytes to a file via FileOutputStream.
For instance objects of the FileInputStream class, if the specified file does not exist, a FileNotFoundException exception is generated when using file data streams for I/O operations. Because it is a non-runtime exception, it must be caught or declared. For instance objects of FileOutputStream class, if the specified file does not exist, the system creates a new file. If so, the new write will overwrite the original data. If an error occurs while reading, writing, or generating a new file, ioExceptions are generated and need to be caught and handled by the programmer.
import java.io.*; public class FileOutputStreamTest { public static void main(String args[]) { try { FileOutputStream out = new FileOutputStream("myFile.txt"); out.write('H'); out.write(69); out.write(76); out.write('L'); out.write('! '); out.close(); } catch (FileNotFoundException e) { System.out.printIn("Error: Cannot open file for Writing.")}catch (IOException e) { System.out.printIn("Error: Cannot write to file.")}}}Copy the code
-
Filter data stream
A filter data stream is created in connection with an existing data stream so that when reading from such a data stream, it provides data that has been specifically processed on the contents of an original input data stream.
-
Buffer data stream
Buffer streams are BufferedInputStream and BufferedOutputStream, which add a buffer to the stream and are filter streams. When reading or writing data, the data goes into the buffer in blocks (block size can be set), and subsequent reads and writes apply to the buffer. This method reduces the speed difference between different hardware devices and improves the EFFICIENCY of I/O operations. At the same time, both streams provide support for methods like mark(), reset(), and skip().
When creating instance objects of this class, you can use either the default buffer size.
FileInputStream fis = new FileInputStream("myFile"); InputStream is = new BufferedInputStream(fis); Copy the code
The other is to set the buffer size yourself
FileInputStream fis = new FileInputStream("myFile"); InputStream is = new BufferedInputStream(fis, 1024); Copy the code
-
Data flow
DataInputStream and DataOutputStream are two such filter data streams that allow reading and writing Java primitives, including Booleans, floating point, and so on, through data streams. Assuming that is and OS are the previously established input/output data flow objects, the data flow creation method is as follows:
DataInputStream dis = new DataInputStream(is); DataOuputStream dos = new DataOutputStream(os); Copy the code
-
-
Object flow
Data streams in Java not only operate on data of basic data types, but also provide the ability to write or read objects from a file data stream through ObjectInputStream and ObjectOutputStream classes in the java.io package. A stream that can input/output objects is called an object stream.
-
Write object flow
Date d = new Data(); FileOutputStream f = new FileOutputStream("date.ser"); ObjectOutputStream s = new ObjectOutputStream(f); try { s.writeObject(d); s.close(); } catch (IOExption e) { e.printStackTrace(); } Copy the code
-
Read object data stream
Date d = null; FileInputStream f = new FileInputStream("date.ser"); ObjectInputStream s = new ObjectInputStream(f); try { d = (Date)s.readObjecte(d); s.close(); } catch(IOException e) { e.printStackTrace(); } System.out.printIn("Date serialized at" + d); Copy the code
-
-
serialization
The ability to record its state for future recovery is called object persistence. To say that an object is persistent means that it can be stored on disk, tape, or passed to another computer for storage in its memory or disk. That is, store objects as some sort of permanent storage type.
Objects describe their state by numbers, and recording objects means recording those numbers. The process of converting an object to a byte sequence is called object serialization, and the process of restoring a byte sequence to an object is called object deserialization. The main task of serialization is to write out the value of the object instance variable. Serialization is a mechanism for dealing with streams of objects, that is, streaming the contents of objects. Serialization is intended to solve problems that occur when reading or writing to a stream of objects.
-
Object structure table
Serialization can only hold non-static members of an object, not any member methods and static members that are given to you, and only the value of the variable is saved, no modifiers for the variable are saved, and access rights have no effect on the serialization of the data domain.
Some object classes, such as Thread classes or stream objects, are not durable because of the nature of their data, which changes frequently and whose state is transient. Such member variables must be identified with the transient keyword, otherwise the compiler will report an error. Any member variables identified with the Transient keyword will not be saved.
When the data variable is an object, the data members of that object can also be persisted. The data structure or structure tree of an object, including its children, constitutes the structure table of the object.
If an object structure table contains a reference to a non-persistent object marked with the keyword TRANSIENT, the object can still be persisted.
-
-
-
Basic character stream
Like InputStream and OutputStream, Reader and Writer are abstract classes that provide only a set of interfaces for character stream processing. Their methods are similar to those of the InputStream and OutputStream classes, except that the arguments are replaced with characters or character arrays.
-
Readers and writers
Java transforms data in data flows between platforms through readers and writers. Unlike other programming languages that use the ASCII character set, Java uses the Unicode character set to represent strings and characters. ASCII represents a character as a byte, and a character can be considered a byte. But Java uses Unicode, a large character set that uses two bytes to represent a character, where the byte is no longer the same as the character. To enable interaction with different platforms in other languages, Java provides a new data-flow processing scheme called reader and writer. Like data streams, there are many different classes that support them in the java.io package, the most important of which are the InputStreamReader and InputStreamWriter classes. These two classes are the interfaces between the byte stream and the reader and writer, and are used to mediate between the byte stream and the character stream. When using these two classes for character processing, there should be some platform specification in the constructor to convert a stream represented in bytes to a character representation on a particular platform
InputStreamReader(InputStream in); // Default specification InputStreamReader(InputStream in, String enc); // Specify the specification OutputStreamWriter(OutputStream out); // Default specification OutputStreamWriter(OutputStream out, String enc); // Specify the specification Copy the code
Readers’ suggestions include the following:
- void close();
- Void mark(interadAheadLimit):
- boolean markSupported();
- Int read();
- Int read(char[] cbuf);
- Int read(char[] chuff, int off, int len);
- boolean ready();
- void reset();
- long skip(long n);
The methods offered by the writer include the following
- void close();
- void flush();
- void write(char[] cbuf);
- void write(char[] cbuf, int off, int len);
- void write(int c);
- void wirte(String str);
- void Write(String str, int off, int len);
-
Buffer readers and buffer writers
As with other I/O operations, format conversions can be more efficient if they are done in large chunks, and for this purpose, BufferReader and BufferedWriter are provided in java.io. The constructor is similar to BufferedInputStream and BufferdOutputStream.
In addition to the read() and write() methods, there are also methods for handling entire lines of characters.
- Public String readLine(): BufferedReader’s method to read a line of characters from the input stream that ends with a ‘\ n’,’\r’, or both.
- Public void newLine(): BufferedWriter’s method that writes an end-of-line flag to the input stream.
import java.io.*; class FileToUnicode { public static void main(String args[]) { try { FileInputStream fis = new FileInputStream("FileToUnicode.java"); InputStreamReader dis = new InputSTreamReader(fis); BufferedReader reader = new BufferdeReader(dis); String s; while((s=reader.readLine())! =null) { System.out.printIn("read: " + s); } dis.close(); } catch(IOException e) { System.out.printIn(e); }}}Copy the code
Example:
import java.io.*; public class PrintWriterTest { public static void main(String args[]) { try { PrintWriter out = new PrintWriter(new FileWriter("myAccout2.txt")); BankAccount aBankAccount = new BankAccount("LiuWei".2017); out.printIn(aBankAccount.getOwnerName()); out.printIn(aBankAccount.getAccountNumber()); out.printIn("$" + aBankAccount.getBalance()); } catch (FileNotFoundException e) { System.out.printIn("Error: Cannot open file for Writing"); } catch (IOException) { System.out.printIn("Error: Cannot write to file"); }}}Copy the code
Example of buffering from a text file:
import java.io.*; public class BufferdeReaderTest { public static void main(String args[]) { try { BufferedReader in = new BufferedReader(new FileReader("myAccount2.txt")); BankAccount aBankAccount = newBankAccount(); aBankAccount.setOwnerNane(in.readLine()); ABankAccount. SetAccountNumber (Integer. The parseInt (in readLine ())); in.read(); aBankAccount.deposit(Floag.parseFloat(in.readLine())); in.close(); System.out.printIn(aBankAccount); System.out.printIn(aBankAccount.getOwnerName() +"" + aBankAccount.getAccountNumber() + "" + aBankAccount.getBalance()); } catch (FileNotFoundException e) { System.out.printIn("Error: Cannot open file for reaading"); } catch (EOFException e) { System.out.printIn("Error: EOF encountered, file may be Corrupted"); } catch (IOException e) { System.out.printIn("Error: Cannot read from file."); }}}Copy the code
-
File handling
Java provides the File class for handling file-related operations. The File object can be used to generate lessons related to a File (and its path) or directory structure. Different systems may have different representations of directory structures, but the File class serves a system-independent purpose, using an abstract path representation. The java.io.File class provides some methods for getting basic information about a File and manipulating it.
-
The File type
Before performing an I/O operation on a file, you must obtain basic information about the file, such as whether it can be read or written, what the absolute path is, and what the length of the file is. The java.io.File class provides tools for getting basic information about files and manipulating files.
A new File object can be created using the following three constructors.
File myFile; myFile = new File("mymotd"); myFile = new File("/"."mymotd"); File myDir = new File("/"); myFile = new File(myDir, "mymotd"); Copy the code
Choose which constructor to use depending on the specifics of the file object. For example, using the first constructor is most practical when only one file is used in an application; However, if you are using several files in the same directory, it is more convenient to use the second or third constructor.
Methods associated with file names
- String getName(): Gets the file name
- String getPath(): obtains the file path
- String getAbsolutePath(): Obtains the absolute file path
- String getParent(): Gets the name of the file’s parent directory
- Boolean renameTo(File new Name): Change filename, return true on success, false otherwise
Document measurement method
- Boolean exists(): Indicates whether the file object exists
- Boolean canWrite(): Specifies whether the file object is writable
- Boolean isFile(): Whether a file object is an object
- Boolean isDirectory(): Whether the file object is a directory
- Boolean isAbsolute(): Specifies whether the file object is an absolute path
Common file information and methods
-
Long lastModified(): Gets the last modification time of the file
-
Long length(): Gets the length of the file
-
Boolean delete(): Deletes the file pointed to by the file object, returning true on success, false otherwise
-
-