File operations and IO

Table of contents

​Edit 1. Get to know the file

1. File path

2. Other knowledge

2. Manipulating files in Java

3. Reading and writing of file contents

1、Reader

2、InputStream

3. Output


1. Understanding documents

 Files are a way to store data on the hard disk. The operating system helps us encapsulate some details of the hard disk.

We only need to understand some interfaces related to files

Hard drives are used to store data. Compared with memory, hard drives have larger storage space, slower access speeds, lower costs, and can store persistently.

The operating system manages the hard disk through modules such as "file systems"

In fact, my computer only has one hard drive. The operating system can abstract this hard drive into multiple hard drives through the file system.  NTFS is a file system on Windows, and there is a certain format behind it to organize hard drive data.

 EXT4 is a common file system on Linux


1. File path

Different file systems have similar ways of managing files.

The "N-ary tree" tree structure is formed through directories and files.

Through the route D drive - tmp - cat.jpg, you can find/determine the only file on your computer. This thing is called a "path"

On Windows, use / or \ to separate different directories

A path starting with a drive letter is also called an "absolute path"

The absolute path is equivalent to the process of finding files starting from "this computer".

Eyepieces starting with . or... are called "absolute paths"

The relative path requires a "base directory"/"working directory", which indicates how to find this folder starting from this base.

If D: is used as the base directory./tmp/cat.jpg If D:tmp is used as the base directory./cat.jpg (. indicates the current directory)

If D:/tmp/111 is used as the base, ..cat.jpg (.. represents the upper-level directory of the current directory)

It is also a cat.jpg file, but the paths found in different base directories are different.


2. Other knowledge

Files stored on the file system can be divided into two major categories:

1. Text file

Characters are stored

For example: utf-8 is a large table. The combination of data on this table can be called characters.

2. Binary files

Stores binary data

How to tell if a file is a text file or a binary file?

The simplest way: open it directly with Notepad

When Notepad opens the file, it tries to query the current data in the code table.

If you can understand it after opening it, it is a text file. If you cannot understand it after opening it, it is a binary file.


2. Manipulating files in Java

Subsequent operations on files, text and binary operations are different.

File system operations: create files, delete files, create directories....

In java, do not use the java.io.file class to describe a file (including a directory) in detail

IO: input and output, we look at input and output from the perspective of the CPU

Describe a specific file through the File object

The File object can correspond to a real file or a file that does not exist.

Construction method:

The string here in the second construction method represents a path, which can be an absolute path or a relative path.

method: 

Looking at it from the perspective of the operating system: directories are also files

Operating system files are a broader concept, specifically there are many different types

1. Ordinary files (commonly seen files)

2. Directory files (commonly seen folders)

On Windows, the separator between directories can be / or \ 

On Linux and Mac, only / is supported

So even on Windows, try to use /, use, and need to be matched with escape characters in the code

You can feel the operation of files through the code:  when we change the absolute path to a relative path, the code running results will be different:

 getAbsolutePath will splice the working directory to the current directory, which is the result of the operation

When running a program in idea, the working directory is the directory where the project is located. When running a program on the command line, the working directory is the directory where the command line is currently located. If the program is running in tomacat, the working directory is the bin directory under tomcat.

This operation may throw an exception

For example, the currently written path is an illegal path

For example, the currently created file does not have permission to operate on the directory where it is located.

Sometimes, you may use such a function: temporary files

When the program is running, a temporary file is created. When the program ends, the temporary file is automatically deleted.

Many productivity software such as Office have the function of generating temporary files. This temporary file automatically saves the intermediate state of your current editing.

Some people don't like to save when using Word. After using it for a period of time, the computer suddenly shuts down and loses power. Will the unsaved data be lost?

Restart the computer. Since it was shut down abnormally just now, the temporary files cannot be deleted. If you start moffice that still exists, you will know that it was shut down abnormally last time. You will be prompted whether you want to restore unsaved data from the previous temporary files. 

 Create directory code:

import java.io.File;
import java.io.FileReader;

public class Demo4 {
    public static void main(String[] args) {
        File file = new File("./test-dir");
        //mk -> make dir->directory
        //mkdir 一次只能创建一层目录,mkdirs 可以一次创建多层目录
        file.mkdir();
        //file.mkdirs();
    }
}

 File renaming can also have the effect of moving files

import java.io.File;

//文件重命名
public class Demo5 {
    public static void main(String[] args) {
        File file = new File("./test.txt");
        File file2 = new File("./src/test2.txt");
        file.renameTo(file2);
    }
}

The above file system operations are all completed based on the File class.

In addition, operations on file content are also required


3. Reading and writing of file contents

1、Reader

The content of the file essentially comes from the hard disk, and the hard disk is managed by the operating system. Using a certain programming language to operate the file essentially requires calling the system's API. 

Although the APIs for operating files in different programming languages ​​are different, the basic steps are the same.

There are four core steps for file content manipulation:

1. Open the file

2. Close the file

3. Read files

4. Write files

Java IO stream is a relatively large system, involving many classes. These different classes have different characteristics, but in general, the methods used are similar.

(1) Construction method, open file

(2) close method, close the file

(3) If it is derived from InputStream or Read, you can use the read method to read data

(4) If it is derived from OutputStream or Writer, you can use the write method to write data

 Read file operation:

 This operation is very important to release necessary resources

To allow a process to open a file, it must apply for certain resources from the system (occupying an entry in the file descriptor table of the process's pcb)

If it is not released, "file resource leakage" will occur, which is a very serious problem.

The file descriptor table can be understood as a sequence table with a limited length and will not automatically expand. Once a file is kept open without closing unused files, the file descriptor table will be filled up and new files cannot be opened in the future. Got it

We can use try with rewsourses to avoid the above problems

At this time, as long as the try code is executed, the close method will be automatically called.

Any object in the file stream can be closed according to the above discussion.

Read an array of char type at a time

 The read content will be filled into the cbuf array of parameters. The parameter here is equivalent to an output parameter.

Through read, an array that was originally empty will be filled with content.

n represents the number of characters actually read

It is equivalent to giving 1024 such a large space. If the file is large enough and exceeds 1024, it can fill this space.

If the file is relatively small, less than 1024, all the contents of the file will be filled into the array (the rest will be empty)

The return value n represents the number of characters actually read.

Sometimes, there may be multiple small files that need to be read and spliced ​​together. You can use this method.

Suppose there are three files, each file is 100 bytes in size

 The final code is as follows:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

//Reader 的使用
public class Demo6 {
    public static void main(String[] args) throws IOException {
/*        //FileReder 的构造方法,可以填写一个路径(绝对路径和相对路径都可以),也可以写一个构造好了的 file 对象
        Reader reader = new FileReader("d:/test.txt");
        try {
            //中间的代码无论出现什么情况,close 都可以执行到
        }finally {
            //如果抛出异常或者 return ,close就都执行不到了
            reader.close();
        }*/

        //上述使用 finally 的方式能解决问题,但是不优雅
        //使用 try with resourses 是更好的解决方法
        try(Reader reader = new FileReader("d:/test.txt")){
            while(true){
                char buf[] = new char[1024];
                int n = reader.read(buf);
                if(n == -1){
                    //读到文件末尾了
                    break;
                }
                for(int i = 0;i < n;i++){
                    System.out.print(buf[i] + " ");
                }
            }
        }
    }
}

2、InputStream

InputStream is a byte stream, its usage is similar to Reader

Text files can also be opened using a byte stream, but each byte you read at this time is not a complete character.

 Read one byte at a time

 Read several bytes at a time and try to fill this byte[]

Read several bytes at a time, filling part of the array

Although Java has char, it is rarely used. String is mostly used. 

Here, we can use some additional tool classes to complete the conversion of bytes/characters --> strings

Although you can also directly use the String construction method to complete the conversion of char[] or byte[] to string, it is more troublesome.

This tool class is Scanner! ! !

In the operating system, the so-called file is a broad concept. System.in is a special file that corresponds to the "standard input". Ordinary files on the hard disk are also files.

Later, the network card (socket) in network programming was also a file

Scanner treats everyone equally and only converts the currently read byte data, but does not care where the data comes from.

However, please note that Scanner is only used to read text files and is not suitable for reading binary files.

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class Demo8 {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("d:/test.txt")){
            Scanner scanner = new Scanner(inputStream);
            //此时就是从 test.txt 这个文件中读取数据了
            String s = scanner.next();
            System.out.println(s);
        }

    }
}

3. Output

The usage of output is very similar to that of input. The key operation is write 

The file needs to be opened before writing, and the file needs to be closed after writing.

The output stream object (whether it is a byte stream or a character stream) will clear the file content after opening the file! ! !

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class Demo8 {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("d:/test.txt")){
            Scanner scanner = new Scanner(inputStream);
            //此时就是从 test.txt 这个文件中读取数据了
            String s = scanner.next();
            System.out.println(s);
        }

    }
}

You can also open it by append writing, and the content will not be cleared at this time. 

Both read and write operations also support random access. You can move the cursor to a specified position for reading and writing, which will not be introduced here.

The method of using OutputStream is exactly the same.

However, the write method cannot support string parameters and can only be written in bytes or byte arrays.


Example: Scan the specified directory and find all ordinary files (excluding directories) whose names contain the specified characters, and then ask the user if they want to delete this file

import java.io.File;
import java.util.Scanner;

public class Demo10 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //1、用户输入一个目录,后续的查找都是针对这个目录进行的
        System.out.println("请输入要搜索的目录");
        File rootPath = new File(scanner.next());

        //2、再让用户输入要搜索和删除的关键粗
        System.out.println("请输入要删除的关键字");
        String word = scanner.next();

        //3、判断当前目录是否有效
        if (!rootPath.isDirectory()){
            System.out.println("此时输入的路径不是合法目录");
            return;
        }

        //4、遍历目录,从根目录出发,按照深度优先(递归) 的方式进行
        scanDir(rootPath,word);
    }
    public static void scanDir(File currentDir,String word){
        //1、先列出当前目录中包含哪些内容
        File[] files = currentDir.listFiles();
        if (files == null || files.length == 0){
            //空的目录或者非法的目录
            return;
        }
        //2、遍历列出的文件,分两个情况进行讨论
        for(File f : files){
            if (f.isFile()){
                //如果当前文件是普通文件,看看文件名是否包含了 word ,来决定是否要删除
                dealFile(f,word);
            }else {
                //如果当前文件是目录文件,就递归执行 scanDir
                scanDir(f,word);
            }
        }
    }
    public static void dealFile(File f,String word){
        Scanner scanner = new Scanner(System.in);
        //1、先判断当前文件是否包含 word
        if (!f.getName().contains(word)){
            //此时文件不包含 word,
            return;
        }
        //2、包含 word,询问用户是否删除该文件
        System.out.println("该文件是: " + f.getAbsolutePath() + ",是否确认删除(Y / N )");
        String choice = scanner.next();
        if (choice.equals("Y") || choice.equals("y")){
            f.delete();
        }
    }
}

Example: Doing a normal file copy

import java.io.*;
import java.util.Scanner;

public class Demo11 {
    public static void main(String[] args) throws IOException {
        System.out.println("请输入要复制的文件路径");
        Scanner scanner = new Scanner(System.in);
        String src = scanner.next();
        File srcfile= new File(src);
        if (!srcfile.isFile()){
            System.out.println("您输入的源文件路径是非法的");
            return;
        }
        System.out.println("请输入要复制到的目标路径");
        String dest = scanner.next();
        File destfile= new File(dest);
        //不要求目标文件存在,但是得保证目标文件所在的目录是存在的
        if (!destfile.getParentFile().isDirectory()){
            System.out.println("您输入的目标文件路径是非法的");
            return;
        }

        //2、进行复制操作的过程,按照字节流打开
        try(InputStream inputStream = new FileInputStream(srcfile);
            OutputStream outputStream = new FileOutputStream(destfile)){
                while(true){
                    byte[] buffer = new byte[1024];
                    int n = inputStream.read(buffer);
                    if (n == -1){
                        System.out.println("读取到 eof,循环结束");
                        break;
                    }
                    outputStream.write(buffer,0,n);
                }
            }
    }
}

Guess you like

Origin blog.csdn.net/weixin_73616913/article/details/132257024