File IO stream of java learning

File IO stream of java learning

0x00 Preface

In some normal development, it is common to let the script run to store some data of the script run results. For example, when developing a crawler, the content we climb down needs to be stored locally, so some operation file classes will be used at this time.

0x01 file class

The file class is mainly used to create, find and delete files and directories.

Let's look at his construction method first

public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent,String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent,String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

Common methods:

public String getAbsolutePath() :返回此File的绝对路径名字符串。
public String getPath() :将此File转换为路径名字符串。
public String getName() :返回由此File表示的文件或目录的名称。
public long length() :返回由此File表示的文件的长度。

Code example:

public static void main(String[] args) {
        String Pathname = "a.txt";
        File abc = new File(Pathname);
        System.out.println(abc.getAbsolutePath());
        String Pathname1 = "a\\a.txt";
        File abc1 = new File(Pathname1);
        System.out.println(abc1.getAbsolutePath());
        System.out.println(abc1.getPath());
        System.out.println(abc1.length());
    }

Judgment method:

public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件。
    public static void main(String[] args) {
        String Pathname = "a.txt";
        File abc = new File(Pathname);
        boolean a = abc.exists();
        System.out.println(a);
        System.out.println(abc.isFile());
        System.out.println(abc.isDirectory());
    }

Addition and deletion function method

public boolean createNewFile() :当前仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :删除由此File表示的文件或目录。
public boolean mkdir() :创建由此File表示的目录。
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。
public static void main(String[] args) throws IOException {
        String Pathname = "a.txt";
        File abc = new File(Pathname);
        boolean file = abc.createNewFile();
        System.out.println(file+"\n"+abc.getAbsolutePath());


       File abc1 = new File("abc");
       abc1.mkdir();

       File abc2 = new File("abc\\abc");
       abc2.mkdirs();
    }

If you are deleting a directory, the deleted directory must be empty to delete.

directory traversal

In file, you can directly obtain all sub files or directories under the file directory.

public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

Code example:

public static void main(String[] args) throws IOException {
        String Pathname = "../";
        File abc = new File(Pathname);
        String[] name = abc.list();
        for (String s : name) {
            System.out.println(s);
        }
    }

Use the list method to get all the files, and then use the enhanced for loop to traverse.

0x02 IO stream overview

IO stream overview

The IO stream in Java refers to the input and output of some file contents. That is, input and output, read and input data to the file.

Byte stream

In the computer, all text data, including pictures, texts and videos, are stored in binary form. Byte stream is a stream that reads and writes data in a byte.

Character stream

A stream of read and write data in one character

0x03 byte stream output stream

OutputStream abstract class is a super class of byte input stream. It defines several common methods.

public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b,int off,int len) :从指定的字节数组写入 len字节,从偏移量 off开始输
出到此输出流。
public abstract void write(int b) :将指定的字节输出流。

After the operation is completed, the resource must be released using the close method.

Fileoutputstream class

Fileoutputstream class is a file output stream, which is used to export data to a file.

View construction method:

public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。

If you create an IO stream object, you must pass in the path of the file. If there is no file, you will create the file. If there is, you will empty the original data.

code:

public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        FileOutputStream FileoutDate = new FileOutputStream(file);
        FileoutDate.write(97);
        FileoutDate.close();
    }

A 97 is written here, but when you open the file, you will find that the written in becomes A. This is because we write here in bytes, and after the ASCII of 97 is converted into a character, it is a.

You can also specify the length of the data to be written out.

public class FileOutput {
    public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        FileOutputStream FileoutDate = new FileOutputStream(file);
        byte[] b = "abce3".getBytes();
        FileoutDate.write(b,2,2);
        FileoutDate.close();
    }
    }

Here, first obtain the byte type data of the character, use write to write, index from the second bit, and write 2 bytes.

In program development, some data may not be able to obtain all results at one time. At this time, if we write the running results in the above way, each cycle will be cleared once and only the last execution result will be obtained. At this time, we can use append and append it into instead of directly overwriting and rewriting.

public FileOutputStream(File file,boolean append) : 创建文件输出流以写入由指定的 File对象表示的
文件。
public FileOutputStream(String name,boolean append) : 创建文件输出流以指定的名称写入文件。

code:

 public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        FileOutputStream FileoutDate = new FileOutputStream(file,true);
        byte[] b = "abce3".getBytes();
        FileoutDate.write(b,2);
        FileoutDate.close();
    }

These lines of code are the same as the previous ones, except that a feature is passed in the fileoutputstream construction method to indicate that the append mode is used, which is false by default.

0x04 byte input stream

InputStream abstract class is a superclass of byte input stream. Byte data can be read into memory.

Common methods:

public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

FileInputStream class

FileInputStream is a file input stream that reads bytes from a file into memory.

Construction method:

FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系
统中的 File对象 file命名。
FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件
系统中的路径名 name命名。

code:

 public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        FileInputStream fileinputdata = new FileInputStream(file);
        int read = fileinputdata.read();
        System.out.println((char) read);
        read = fileinputdata.read();
        System.out.println((char) read);
        read = fileinputdata.read();
        System.out.println(read);
        fileinputdata.close();
    }

After using the read method, the address will be pushed back by one bit. If you know whether it has been read, it will return - 1.

The above methods are to read a single byte. We can define a byte type value and let it read the length we specify each time.

code:

    public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        FileInputStream fileinputdata = new FileInputStream(file);
        int len;
        byte[] b = new byte[2];
        while ((len=fileinputdata.read(b))!=-1){
            System.out.println(new String(b,len));
        }
        fileinputdata.close();
    }

Here, the B variable is defined to receive the length of the data output read each time, and then a len variable is defined to receive the data read each time. Here, the assignment can be directly placed in the cycle condition. If the assigned variable is not equal to - 1, the cycle will continue until it is read to - 1, and the cycle will be stopped. As mentioned earlier, if there is no data read, the output will return a - 1 to end the cycle.

0x05 character stream

During byte reading and writing, some Chinese characters may display garbled code. Because a Chinese character may occupy multiple bytes. Therefore, if character data is read and written, character stream can be used to process the data.

Character input stream

Reader abstract class is a super class used to read character stream, which can read character information into memory.

Common methods:

public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() : 从输入流读取一个字符。
public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。

FileReader class

Construction method:

FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。

To create a stream object, you must pass in a file path.

Construction method definition code:

 public static void main(String[] args) throws IOException {
    File file = new File("a.txt");
        FileReader filereader = new FileReader(file);
    }
或者:
public static void main(String[] args) throws IOException {
        
        FileReader filereader = new FileReader("a.txt");
    }

Read single character data:

public static void main(String[] args) throws IOException {

        FileReader filereader = new FileReader("a.txt");
        int b;
        while ((b = filereader.read())!=-1){
            System.out.println((char)b);
        }
    }

Read multiple character data:

 public static void main(String[] args) throws IOException {

        FileReader filereader = new FileReader("a.txt");
        int b;
        char[] buf = new char[2];
        while ((b = filereader.read(buf))!=-1){
            System.out.println(new String(buf));
        }
    }

Character output stream

The writer abstract class is a super tired character output stream, which writes the known character information to the specified place.

Common methods:

void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf,int len) 写入字符数组的某一部分,off数组的开始索引,len
写的字符个数。
void write(String str) 写入字符串。
void write(String str,int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个
数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。

Filewriter class

The filewriter class is a class that writes characters into a file. The default character encoding and the default byte buffer are used during construction.

Construction method:

FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。

Write data code:

public static void main(String[] args) throws IOException {

        FileWriter filewriter = new FileWriter("a.txt");
        filewriter.write("二狗");
        filewriter.write(97);
        filewriter.write(156);
        filewriter.flush();
        filewriter.close();
    }

The code here cannot write data without writing the flush method and close. Let's look at the difference between the two methods:

flush :刷新缓冲区,流对象可以继续使用。
close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

0x06 cache stream

Byte stream and character stream will access the hard disk every time they read and write. When the reading and writing frequency increases, its access efficiency is not high, but when using cache stream to read, a large amount of data will be read into the cache first. After each reading, access the cache first until the cache is read, and then read to the hard disk. The same is true for cache stream writing data. First write the data into the cache area until the cache area reaches a certain amount, Write these data to the hard disk together, which reduces IO operations.

字节缓冲流: BufferedInputStream , bufferedoutputstream
字符缓冲流: BufferedReader , BufferedWriter

Byte cache output stream

Construction method:

public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
public bufferedoutputstream(OutputStream out) : 创建一个新的缓冲输出流。

code:

    public static void main(String[] args) throws IOException {

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
        bufferedoutputstream bos = new bufferedoutputstream(new FileOutputStream("A.txt"));

        int b ;
        while ((b = bis.read())!=-1){
            bos.write(b);
        }
    }

The above code uses the byte cache stream to copy and paste a file. If the byte output stream is used, it is very slow. The speed of reading and writing using byte cache stream will be very fast.

If we want to make reading and writing faster, we can define the length of each reading and writing, and let it be fixed to the length of each reading and writing.

    public static void main(String[] args) throws IOException {

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
        bufferedoutputstream bos = new bufferedoutputstream(new FileOutputStream("A.txt"));

        int b ;
        byte[] bytes = new byte[8*1024];
        while ((b = bis.read(bytes))!=-1){
            bos.write(bytes,b);
        }
    }

Read and write 8 * 1024 bytes each time to reduce the time of file reading and writing.

Character cache stream

Construction method:

public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。

code:

public static void main(String[] args) throws IOException {
        BufferedReader bis = new BufferedReader(new FileReader("a.txt"));
            String b = null ;
            while ((b = bis.readLine())!=null){
                System.out.println(b);
            }
            bis.close();
    }

Use readLine to read the current line data.

0x07 serialization and deserialization

summary

Java provides a mechanism for object serialization. An object is represented by a byte sequence, which contains object data, object type and object storage properties. After the byte sequence is written out to the file, it is equivalent to persistently reporting an object information error. This process is called serialization.

Conversely, the byte sequence stored in the file is read from the file, the object is reconstructed and reused to create the object. This step is called deserialization.

Objectoutputstream class

Objectoutputstream class writes out the original data type of Java object to a file to realize the persistent storage of the object. That is, a class that serializes objects.

Construction method:

public ObjectOutputStream(OutputStream out)

matters needing attention:

code:

创建一个类:

public class Method implements Serializable {
    public String name;
    public String address;
    public transient int age;
    public void method(){
        System.out.println(name +address);
    }

}

main方法:

public static void main(String[] args) {
        Method e = new Method();
        e.name = "zhangsan";
        e.address = "beiqinglu";
        e.age = 20;

        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("a.txt"));
            out.writeObject(e);
            out.close();
            System.out.println("ok");

        } catch (IOException ioException) {
            ioException.printStackTrace();
        }finally {
        }
    }

Looking at the a.txt file, you can see that the displayed characters are garbled because the object is serialized and written into an object instead of some characters.

Objectinputstream class

Objectinputstream deserializes the stream and restores the original data previously serialized with objectoutputstream to objects

Construction method:

public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。

Deserialization method 1

If we need to deserialize the serialized object and restore it from the file, we call the readObject method of objectoutputstream to read an object.

public final Object readObject () : 读取一个对象。

code:

 public static void main(String[] args) {
        Method e = null;
        try {
            FileInputStream fis = new FileInputStream("a.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
             e = (Method) ois.readObject();
            ois.close();
            fis.close();
        } catch (IOException | ClassNotFoundException ioException) {
            ioException.printStackTrace();
        }
        System.out.println("name="+e.name);
        System.out.println("address ="+e.address);
        System.out.println("age="+e.age);
    }

Deserialization method 2

When the JVM serializes an object, it can find the class attribute, but if the class file is modified after serialization, the deserialization operation must fail and an invalidclassexception will be thrown.

There are three reasons for throwing invalidclassexception:

The serializable interface provides a serial version number to the class to be serialized. SerialVersionUID this version number is used to verify whether the serialized object and the corresponding class match.

public class Employee implements java.io.Serializable {
// 加入序列版本号
private static final long serialVersionUID = 1L;
public String name;
public String address;
// 添加新的属性,重新编译,可以反序列化,该属性赋为默认值.
public int eid;
public void addressCheck() {
System.out.println("Address check : " + name + " ‐‐ " + address);
}
}

0x08 summary


File类:用于创建删除文件与文件夹。

FileoutputStream:字节输出流,用于将字节写出到文件中。

FileinputStream:字节输出流,用于读取文件中的字节。

FileReader类是表示用于读取字符流,可以读取字符信息到内存中。

FileWriter类是写出字符到文件中的一个类,,构造时候使用默认的字符编码和默认的字节缓冲区。

字节缓冲流: BufferedInputStream , bufferedoutputstream

字符缓冲流: BufferedReader , BufferedWriter

0x09 end

This article has a lot of content. I also wrote a simple summary later. This article also wrote me for about 2 days. Later, we will study some deserialization vulnerabilities exposed in history.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>