Input / output stream

file

  1. file

    File is the place to save data, such as word, video and audio. Files exist as streams in programs

  2. flow

    The distance that data travels between the data source and the program (memory)

  3. Input stream

    The path of data from the data source (file) to the program (memory)

  4. Output stream

    The path of data from the program (memory) to the data source (file)

    I / O is relative to memory

Common operations for creating file objects

File class is mainly used to obtain or process information related to disk files, such as file name, file path, access rights and modification date. It can also browse the subdirectory hierarchy. The file class does not have the function of reading information from and writing information to a file. It only describes the attributes of the file itself.

  1. new File(String pathName): build a File object according to the path name
  2. new File(File parent,String child): built according to the parent directory file + child path
  3. New fill (string parent, string child): built according to parent directory + child path
File file = new File("d:\\new1.txt");
file.createNewFile();

File file1 = new File("d:\\");
File file2 = new File(file1, "new2.txt");
file2.createNewFile();

File file3 = new File("d:\\","new3.txt");
file3.createNewFile();

Get relevant information

  1. getName() get file name
  2. getAbsoultPath() gets the absolute path of the file
  3. getParent() get parent directory
  4. length() file length bytes
  5. Does the exists() file exist
  6. Is isFIle() a file
  7. Is isDirectory() a directory
  8. delete() deletes an empty directory or file
  9. makdir()/makdirs() create one level directory / multi-level directory
File file = new File("d:\\news2.txt");

//Gets the name of the file
System.out.println("File name"+file.getName());
//Gets the absolute path of the file
System.out.println("File absolute path"+file.getAbsolutePath());
//Gets the parent directory of the file
System.out.println("File parent directory"+file.getParent());
//Get the file size (bytes) utf-8 number, one byte for English, three bytes for Chinese, and two bytes for carriage return
System.out.println("File size (bytes)"+file.length());
//Does it exist
System.out.println("Does it exist"+file.exists());
//Is it a directory
System.out.println("Is it a directory"+file.isDirectory());
//Is it a file
System.out.println("Is it a file"+file.isFile());

Creation / deletion of file directory

  1. Deletion of files
public void deleteFile(){
    String filePath = "d:\\news2.txt";
    File file = new File(filePath);
    //Determine whether the file exists
    if(file.exists()){
        //If the file is deleted successfully, true is returned
        if(file.delete()){
            System.out.println("Delete succeeded");
        }else {
            System.out.println("Deletion failed");
        }
    }else {
        System.out.println("file does not exist");
    }
}
  1. Directory deletion
//Judge whether there is a directory and delete it if it exists (there is no content in the directory)
//A directory can be said to be a special file
@Test
public void deleteDir(){
    String filePath = "d:\\dir";
    File file = new File(filePath);
    if(file.exists()){
        //When there is content in the directory, it cannot be deleted
        if(file.delete()){
            System.out.println("Delete succeeded");
        }else {
            System.out.println("Deletion failed");
        }
    }else {
        System.out.println("file does not exist");
    }
}
  1. Directory creation
//Determine whether a directory exists, and create it if it does not exist
@Test
public void createDir(){
    String filePath = "d:\\dir1\\sss1\\sss2";
    File file = new File(filePath);
    if(file.exists()){
        System.out.println("File exists");
    }else {
        //mkdirs can create multi-level directories, while mkdir can only create a single directory
        if(file.mkdirs()){
            System.out.println("File created successfully");
        }else {
            System.out.println("File creation failed");
        }
    }
}

I/O flow

  • I/O is short for input/output, which is generally used to process data transmission.
  • In java files, the input and output operations of data are carried out in the "stream" method
  • java.io package provides various "stream" classes and interfaces to obtain different types of data and input and output data through methods

Stream classification

  1. Operation data unit: byte stream (8bit), binary file, lossless operation, character stream (text file)
  2. Direction of flow: input, output
  3. The role of flow: node flow, processing flow / wrapper flow
(abstract base class)Byte streamCharacter stream
Input streamInputStreamReader
Output streamOutputStreamWriter
  • The I/O flow of java involves more than 40 classes, which are actually derived from the above four abstract classes
  • The child class names derived from these four classes all use their parent class as the suffix of the child class name

InputStream

FileInputStream (byte input stream)

Single byte read
public void readFile(){
    //File read directory
    String filePath = "d:\\news2.txt";
    //Accept read return bytes
    int readDate;
    FileInputStream fileInputStream = null;
    try {
        fileInputStream = new FileInputStream(filePath);
        //Read a single byte and return - 1 when it reaches the end of the document
        while ((readDate = fileInputStream.read()) != -1){
            System.out.print((char)readDate);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Byte array

Here, there must be a readline to store the length of the obtained data, because the data in bytes is overwritten after read. That is to say, even if only three bytes of data are read at last, there is the last read result in the last five bits of the byte array.

public void readFile02(){
    //File read directory
    String filePath = "d:\\news2.txt";
    //Byte array
    byte[] bytes = new byte[8];//Read eight bytes at a time
    //Read byte length
    int readLine = 0;
    FileInputStream fileInputStream = null;
    try {
        fileInputStream = new FileInputStream(filePath);
        //Eight byte read, normal read returns the length of read bytes
        //Returning - 1 indicates that the reading has ended
        while ((readLine = fileInputStream.read(bytes)) != -1){
            System.out.print(new String(bytes,0,readLine));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ObjectIntputStream

  • Generally used for deserialization operations
  • When reading serialized files, the reading order should be consistent with the writing order
  • When using the readObject method to read an Object, the compile type is Object and the run type is the corresponding type
  • If you want to force a type to be converted to a corresponding type, you must have the orientation permission of the corresponding class
Deserialization
  • Deserialization is to reload the serialized data into memory (restore to the original data type and value)
String desPath = "D:\\xxx";

ObjectInputStream ism = new ObjectInputStream(new FileInputStream(desPath));
System.out.println(ism.readInt());
System.out.println(ism.readBoolean());
System.out.println(ism.readChar());
System.out.println(ism.readDouble());
System.out.println(ism.readUTF());
Object object = ism.readObject();
Dog dog = (Dog) object;
dog.show();

ism.close();

OutPutStream

Fileoutputstream (byte output stream)

When the specified file does not exist, it will be automatically created. If the directory does not exist, an error FileNotFoundException will be reported

public void writer(){
    String text = "Hello,World!";
    String filePath = "d:\\news2.txt";
    FileOutputStream fileOutputStream = null;
    try {
        //The default write is overwrite. If you want to write after the file content, add a true in the construction method
        //fileOutputStream = new FileOutputStream(filePath,true);
        fileOutputStream = new FileOutputStream(filePath);
        //Output single character
        //fileOutputStream.write('H');
        //Write string
        //fileOutputStream.write(text.getBytes());
        //Select part of the contents from the byte array to write
        fileOutputStream.write(text.getBytes(),0,text.length());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
File copy
String srcPath = "d:\\picture\\1.jpg";
String descPath = "d:\\01.jpg";
FileOutputStream outputStream = null;
FileInputStream inputStream = null;

try {
    inputStream = new FileInputStream(srcPath);
    outputStream =  new FileOutputStream(descPath);
    byte[] bytes = new byte[1024];
    int readLength = 0;
    while ((readLength = inputStream.read(bytes)) != -1 ){
        outputStream.write(bytes,0,readLength);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if(inputStream!= null){
            inputStream.close();
        }
        if(outputStream != null){
            outputStream.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

ObjectOutputStream

  • ObjectOutputStream is an object processing stream and a wrapper stream
  • It is generally used to realize the serialization of objects (save the value and type of data when saving data)
  • The format saved after serialization is independent of the set name suffix
serialize
  • The class to serialize must implement one of two interfaces

    • Serializable: recommended. This is a tag interface. You don't need to implement any methods
    • Externalizable
  • SerialVersionUID constant can be added to the serialization class, Improve version compatibility (Ps: when you do not set it, the interface will generate a serialVersionUID by default, and this value will be saved when you serialize it. If your original class has been modified after serialization, the serialVersionUID generated by default will change. After deserialization, if the values of the two serialvsersionuids are different, an InvalidClassException error will be reported.)

    private static final long serialVersionUID = 1;
    
  • When serializing, all attributes of the default class will be serialized to handle members decorated with static and transient

  • Serialization has inheritance. If the parent class implements the interface, the child class also implements serialization by default

    //The file format saved after serialization is not plain text, but is stored according to its format
    String descPath = "D:\\xxx";
    ObjectOutputStream objectOutputStream = null;
    
    objectOutputStream  = new ObjectOutputStream(new FileOutputStream(descPath));
    // int ->Integer
    objectOutputStream.writeInt(22);
    //boolean ->Boolean
    objectOutputStream.writeBoolean(true);
    //char -> Character
    objectOutputStream.writeChar('a');
    //double ->Double
    objectOutputStream.writeDouble(9.5);
    //String
    objectOutputStream.writeUTF("Leeson ");
    objectOutputStream.writeObject(new Dog("Zhang San"));
    

Reader

FileReader

  • new FileReader(File/String)

  • read(): read a single character, return the character, and return - 1 at the end of the file

  • read(Char []): read multiple character arrays in batch, return the number of characters read, and return - 1 at the end of the file

    Related API

  • new String(char []): convert char [] to String

  • New string (char [], off, len): converts the specified part of char [] into characters

Single character
String filePath = "d:\\new1.txt";
FileReader fileReader = null;
int data = 0;
try {
    fileReader = new FileReader(filePath);
    while ((data = fileReader.read()) != -1){
        System.out.print((char)data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Multiple characters
String filePath = "d:\\new1.txt";
FileReader fileReader = null;
int readLen = 0;
char[] readDate = new char[8];
try {
    fileReader = new FileReader(filePath);
    while ((readLen = fileReader.read(readDate)) != -1){
        //Determine the write length through readLen to prevent writing the uncovered contents in the array
        System.out.print(new String(readDate,0,readLen));
    }
} catch (IOException e) {
    e.printStackTrace();
}finally {
    fileReader.close();
}

BufferedReader

bufferedReader belongs to character stream and operates on characters.

When closing the processing flow, you only need to close the outer layer. It will automatically call the clos() method of the inner node flow.

The following uses the try with resource method to close resources. This is a syntax sugar. The compiler will handle it in the way we wrote before when compiling.

String filePath = "d:\\novel.txt";
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))){

    String line = null;
    //Returns the read character. When it is not read, it will be null
    while ((line = bufferedReader.readLine()) != null){
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

InputStreamReader

The InputStreamReader class is a bridge from byte stream to character stream: it reads bytes using the specified character set and decodes them into characters. The character set it uses can be specified by name or explicitly, or it can accept the default character set of the platform.

String srcPath = "D:\\Download\\IDM\\Novel 1.txt";
InputStreamReader inputStreamReader = null;
try {
    //The default read file is utf-8, and other types cause garbled code
    inputStreamReader = new InputStreamReader(new FileInputStream(srcPath),"gbk");
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    System.out.println(bufferedReader.readLine());
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if(inputStreamReader != null){
        try {
            inputStreamReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Writer

FileWriter

  • new FileWriter(File/String): overwrite mode, which is equivalent to the flow in the first segment of the pointer

  • New filewriter (file / string, true): append mode, equivalent to the stream at the end of the pointer

  • write(int): writes a single character

  • write(char []): writes the specified array

  • write(char[],off,len): writes the specified part of the specified array

  • write(String): writes the entire string

  • write(String,off,len): writes the specified part of the string

    Related API

  • String::toCharArray(): convert string to character array

Note: after using FileWriter, you must close or flush, otherwise the specified file cannot be written.

String filePath = "d:\\new1.txt";
FileWriter fileWriter = null;
try {
    //fileWriter =  new FileWriter(filePath);
    fileWriter =  new FileWriter(filePath,true);
    char[] chars = {0,1,2};
    fileWriter.write('H');//Write a single character
    fileWriter.write("How do you do");//Write string
    fileWriter.write("How do you do",0,1);//Intercept write
    fileWriter.write(chars,0,1);
    fileWriter.write(chars);//Write array
} catch (IOException e) {
    e.printStackTrace();
}finally {
    try {
        //Both must be written in order to write to the file
        //fileWriter.flush();
        //close is equivalent to write + closing the stream
        //The bottom layer of both calls the write method of outputStream
        fileWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

BufferedWriter

BufferedWriter is a character wrapper stream used to output character information.

String filePath = "d:\\12.txt";
//BufferedWriter does not provide a constructor for append mode. To use append mode, add true to the constructor of node flow
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true))) {
    //Insert string
    bufferedWriter.write("Hello world!");
    //Insert a system related line feed
    bufferedWriter.newLine();
    bufferedWriter.write("111111");
}catch (IOException e){
    e.printStackTrace();
}

BufferedCopy

  • This operation is based on characters. Do not operate binary files [sound, video, pdf,doc, picture]
  • Try with resources syntax
String srcPath = "D:\\Download\\IDM\\novel.txt";
String descPath = "D:\\Download\\IDM\\novel copy.txt";
String line = null;
try (BufferedReader bufferedReader =  new BufferedReader(new FileReader(srcPath)); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(descPath));){
    while ((line = bufferedReader.readLine()) != null){
        bufferedWriter.write(line);
        //Insert a new line
        bufferedWriter.newLine();
    }
} catch (IOException e) {
    e.printStackTrace();
}

OutputStreamWriter

OutputStreamWriter is a bridge from character stream to byte stream: encodes the characters written into it into bytes using the specified character set. The character set it uses can be specified by name or explicitly, or it can accept the default character set of the platform.

//To create a conversion object, utf-8 is used by default
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\1.txt"),"gbk");
//Use buffered streams to improve efficiency
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
bufferedWriter.write("Hello");
//The object is written only when the stream is closed
bufferedWriter.close();

Properties

The class used to load the configuration file

  • Load: load the key value pair of the configuration file to the Properties object
  • list: displays data to the specified device
  • getProperty(key): get the value according to the key
  • setProperty(key,value): sets the key value pair to the Property object
  • store: put the key value pair in the Properties object into the configuration file. In the idea, if the key value pair contains Chinese, it will be stored as unicode code (FileOutputStream)
//1. Create Properties object
Properties properties = new Properties();
//2. Load the specified configuration file (load accepts a Reader)
properties.load(new FileReader("base/IO_Demo/src/mysql.Properties"));
//3. Display k-v to control (list method accepts character or byte print stream)
properties.list(System.out);
//4. Obtain the corresponding value according to the key
System.out.println(properties.getProperty("user"));
//Create Properties object
Properties newPro = new Properties();
//Write key value pairs to the Properties object
newPro.setProperty("name","Zhang San");
//Write the key value pairs in the object to the configuration file (Writer/OutputStream,comment comment)
newPro.store(new FileOutputStream("base/IO_Demo/src/user.Properties"),"hello");

Node flow and processing flow

Node flow

Process for a specific data source (read the output from a specific data source, such as FileReader and filewriter can only get data from files), such as files, arrays, pipes and strings. Lack of flexibility.

  • Node flow is directly connected with data and is the underlying flow
Buffered wrapper flow case

Realize the copy of text file

  • This is using the syntax sugar try with resources
  • Do not operate binary files [pictures, pdf, video, sound...] when using reader and writer operations, which may cause file damage
String srcPath = "D:\\Download\\IDM\\FSD.mp4";
String descPath = "D:\\Download\\IDM\\FSDCopy.mp4";
String line = null;
try (BufferedReader bufferedReader =  new BufferedReader(new FileReader(srcPath)); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(descPath));){
	while ((line = bufferedReader.readLine()) != null){
        bufferedWriter.write(line);
        //Insert a new line
        bufferedWriter.newLine();
    }
} catch (IOException e) {
    e.printStackTrace();
}

Processing flow / packaging flow

The node flow is packaged to provide more powerful reading and writing functions for the program.

  • It can eliminate the difference of different node flows
  • Using decorator mode, you do not connect directly to the data source
  • Increased cache efficiency
  • Provide a convenient way to process a large amount of data at one time

This is part of the source code of Bufferedread. You can see that it inherits the Read class and has a private domain of Reader type.

public class BufferedReader extends Reader {
    private Reader in;
    private char cb[];
    private int nChars, nextChar;

It has two constructors, which can see that all the objects accepted are of Reader type, which means that it can accept all the objects of Reader subclasses, so it can handle the node flow related to Reader, which is more powerful.

public BufferedReader(Reader in, int sz) 
public BufferedReader(Reader in)

Keywords: Java

Added by rallan on Fri, 24 Dec 2021 00:40:38 +0200