Java advanced File class, node stream, buffer stream, conversion stream, standard I/O stream, print stream, data stream

Chapter 13 IO Stream

1. Use of File class

  1. An object of the File class, representing a file or a file directory (commonly known as: folder)
  2. The FiLe class is declared java.iounder the package
  3. The File class involves methods such as the creation, deletion, renaming, modification time, and file size of files or file directories, but does not involve the operation of writing or reading file contents. If you need to read or write file content, you must use Io streams to complete it.
  4. Subsequent objects of the File class are often passed to the constructor of the stream as parameters to indicate the "end point" of reading or writing.

1.1. How to create an instance of the File class

File(String filePath)
File(String parentPath, String childPath)
File(String parentFile, String childPath)
  1. Relative path: compared to a specified path.

  2. Absolute path: the path to a file or file directory including the drive letter

  3. Path separator:

    windows: \\

    unix: /

illustrate:

IDEA中: If the development uses unit testing in JUnit, the relative path is under the current Module. If you use main() to test, the relative path is under the current Project.

Eclipse中: Regardless of whether you use the unit test method or main() test, the relative path is under the current Project.

1.2. Commonly used methods

1.2.1. Obtaining function of File class

public String getAbsolutePath():获取绝对路径
public String getPath() :获取路径
public String getName() :获取名称
public String getParent():获取上层文件目录路径。若无,返回null
public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
public long lastModified() :获取最后一次的修改时间,毫秒值
public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
@Test
public void test2(){
    
    
    File file1 = new File("hello.txt");
    File file2 = new File("D:\\JAVA NOTES\\核心基础笔记\\Java高级编程\\hi.txt");
    System.out.println(file1.getAbsoluteFile());
    System.out.println(file1.getPath());
    System.out.println(file1.getName());
    System.out.println(file1.getParent());
    System.out.println(file1.length());
    System.out.println(new Date(file1.lastModified()));


    System.out.println("----------------------");
    System.out.println(file2.getAbsoluteFile());
    System.out.println(file2.getPath());
    System.out.println(file2.getName());
    System.out.println(file2.getParent());
    System.out.println(file2.length());
    System.out.println(file2.lastModified());
}

@Test
public void test3(){
    
    
    File file = new File("F:\\ProjectsLocation\\IdeaProjects\\Indomitable\\src");
    String[] list = file.list();
    for (String s:list){
    
    
        System.out.println(s);
    }

    File[] listFiles = file.listFiles();
    for (File f:listFiles){
    
    
        System.out.println(f);
    }
}

1.2.2. Renaming function of File class

/**
 * public boolean renameTo(File dest):把文件重命名为指定的文件路径
 * 比如: file1.renameTo(file2)为例:
 *      要想保证返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在。
 */
@Test
public void test4(){
    
    
    File file1 = new File("hello.txt");
    File file2 = new File("he.txt");

    boolean rename = file1.renameTo(file2);
    System.out.println(rename);
}

1.2.3. Judgment function of File class

public boolean isDirectory():判断是否是文件目录 

public boolean isFile() :判断是否是文件 

public boolean exists() :判断是否存在 

public boolean canRead() :判断是否可读 

public boolean canWrite() :判断是否可写 

public boolean isHidden() :判断是否隐藏
@Test
public void test5(){
    
    
    File file1 = new File("F:\\ProjectsLocation\\IdeaProjects\\Indomitable\\src");

    System.out.println(file1.isDirectory());
    System.out.println(file1.isFile());
    System.out.println(file1.exists());
    System.out.println(file1.canRead());
    System.out.println(file1.canWrite());
    System.out.println(file1.isHidden());

    System.out.println("***************");

    File file2 = new File("hello.txt");

    System.out.println(file2.isDirectory());
    System.out.println(file2.isFile());
    System.out.println(file2.exists());
    System.out.println(file2.canRead());
    System.out.println(file2.canWrite());
    System.out.println(file2.isHidden());
}

1.2.4. Creation function of File class

public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false

public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。
如果此文件目录的上层目录不存在,也不创建。

public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建
注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目
路径下。
@Test
public void test7(){
    
    
    //文件目录的创建
    File file1 = new File("D:\\Java\\1.尚硅谷全套JAVA教程--基础阶段(73.36GB)\\尚硅谷宋红康Java核心基础_好评如潮\\Java基础全套视频教程\\day25_泛型与File\\20230527");

    boolean mkdir = file1.mkdir();
    if (mkdir){
    
    
        System.out.println("创建成功1");
    }

    File file2 = new File("D:\\Java\\1.尚硅谷全套JAVA教程--基础阶段(73.36GB)\\尚硅谷宋红康Java核心基础_好评如潮\\Java基础全套视频教程\\day25_泛型与File\\20230528");
    boolean mkdirs = file2.mkdirs();//级联创建
    if (mkdirs){
    
    
        System.out.println("创建成功2");
    }
}

1.2.5. Delete function of File class

public boolean delete():删除文件或者文件夹
删除注意事项:
Java中的删除不走回收站。
要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录

2. IO flow principle and flow classification

2.1. Java IO principles

  1. I/O is the abbreviation of Input/Output. I/O technology is a very practical technology used to handle data transmission between devices. Such as reading/writing files, network communication, etc.
  2. In Java programs, data input/output operations are performed in a "stream" manner.
  3. Various "stream" classes and interfaces are provided under the java.io package to obtain different types of data and input or output data through standard methods.

image.png

输入input: Read external data (data from storage devices such as disks and optical disks) into the program (memory).

输出output: Output program (memory) data to storage devices such as disks and optical disks.

2.2. Stream classification/architecture

  • According to different operating data units, it is divided into: byte stream (8 bit), character stream (16 bit)
  • According to the different flow directions of data flow, it is divided into: input stream and output stream.
  • According to the different roles of the flow , it is divided into: node flow, processing flow
image.png

Schematic diagram of flow classification understanding:

image.png

3. Node flow (or file flow)

* 抽象基类             节点流(或文件流)           缓冲流(处理流的一种)
InputStream          FileInputStream (read(byte[] buffer))       BufferedInputStream (read(byte[] buffer,0,len))
 * OutputStream         FileOutPutStream (write(byte[] buffer,0,len))     BufferedOutputStream (write(byte[] buffer))
 * Reader               FileReader (read(char[] cbuf))              BufferedReader (read(char[] cbuf))
 * Writer               FileWriter (write(char[] cbuf,0,len))             BufferedWriter (write(char[] cbuf,0,len))

image.png

Steps in this chapter:

1.实例化File类的对象,指明要操作的文件
2.提供具体的流
3.数据的读入
4.流的关闭操作

3.1. Read data FileReader

    @Test
    public void test1(){
    
    
        FileReader fr = null;
        try {
    
    
            //1.实例化File类的对象,指明要操作的文件
            File file = new File("hello.txt ");//相较于当前Module
            //2.提供具体的流
            fr = new FileReader(file);
            //3.数据的读入
            //read():返回读入的一个字符。如果达到文件末尾,返回 -1
            //方式一
//        int data = fr.read();
//        while (data != -1){
    
    
//            System.out.print((char)data);
//            data = fr.read();
//        }

            //方式二:语法上针对方式一的修改
            int data;
            while ((data = fr.read()) != -1){
    
    
                System.out.print((char)data);
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
        }finally {
    
    
            //4.流的关闭操作
            try {
    
    
                //可能会有空指针异常
                if (fr != null){
    
    
                    fr.close();
                }
            }catch (Exception e){
    
    
                e.printStackTrace();
            }
        }
    }

Upgrade the read() operation: use the overloaded method of read

@Test
    public void test2() throws IOException {
    
    
        FileReader fr = null;
        try {
    
    
            //1.File类的实例化
            File file = new File("hello.txt ");//相较于当前Module
            //2.FileReader流的实例化
            fr = new FileReader(file);
            //3.读入的操作
            char[] cbuf = new char[5];
            int len;
            while ((len = fr.read(cbuf)) != -1){
    
    
//                //方式一
//                for (int i=0;i<len; i++){
    
    
//                    System.out.print(cbuf[i]);
//                }

                //方式二
                String s = new String(cbuf, 0, len);
                System.out.print(s);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                //4.资源的关闭
                if (fr != null){
    
    
                    fr.close();
                }
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
    }

3.2. Write data FileWriter

The operation of writing data from memory to a hard disk file

illustrate:

  1. For output operations, the corresponding File does not need to exist and no exception will be reported.

  2. If the file on the hard disk corresponding to File does not exist, this file will be automatically created during the output process.

    If the file on the hard disk corresponding to File exists:

    ​ ① If the constructor used by the stream is FileWriter(file, false) / FileWriter(file): overwriting the original file

    ​ ② If the constructor used by the stream is FileWriter(file, true): the original file will not be overwritten, but the content will be appended to the original file.

/**
     * 从内存中写出数据的到硬盘文件的操作
     * 说明:
     * 1.输出操作,对应的File可以不存在,并不会报异常
     * 2.File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件
     *   File对应的硬盘中的文件如果存在:
     *      如果流使用的构造器是 FileWriter(file, false) / FileWriter(file):对原有文件的覆盖
     *      如果流使用的构造器是 FileWriter(file, true):不会对原有文件覆盖,而是在原有文件基础上追加内容
     */
@Test
public void  testFileWriter() throws IOException {
    
    
    //1.提供File类的对象,指明写出搭配的文件
    File file = new File("hello1.txt");

    //2.提供FileWriter的对象,用于数据的写出
    FileWriter fw = new FileWriter(file, true);

    //3.写出的操作
    fw.write("I hava a little dream!\n");
    fw.write("You need to hava a dream!\n");

    //4.流资源的关闭
    fw.close();
}

3.3. Use FileReader and FileWriter to copy text files

step:

1.创建File类的对象,指明读入和写出的文件
2.提供输入流和输出流的对象
3.数据的读入和写出操作
4.关闭流资源
@Test
public void testFileReaderFileWriter(){
    
    
    FileWriter fw = null;
    FileReader fr = null;
    try {
    
    
        //1.创建File类的对象,指明读入和写出的文件
        File srcFile = new File("hello.txt");
        File destFile = new File("hello2.txt");

        //2.提供输入流和输出流的对象
        fr = new FileReader(srcFile);
        fw = new FileWriter(destFile);

        //3.数据的读入和写出操作
        char[] cbuf = new char[5];
        int len;//记录每次读入到cbuf数组中的字符个数
        while ((len = fr.read(cbuf)) != -1){
    
    
            //每次写出 len个字符
            fw.write(cbuf, 0, len);
        }

    } catch (IOException e) {
    
    
        throw new RuntimeException(e);
    } finally {
    
    
        //4.关闭流资源
        try {
    
    

            if (fw != null) {
    
    
                fw.close();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

        try {
    
    
            if (fr != null){
    
    
                fr.close();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

3.4、FileInputStream

Summarize:

  • 1. For text files (.txt, .java, .c, .cpp), use character stream processing
  • 2. For non-text files (.jpg, .mp3, .mp4, .avi, .doc, .ppt, …), use byte stream processing
/**
 * 使用字节流 FileInputStream 处理文本文件,可能出现乱码
 */
@Test
public void test1() throws IOException {
    
    
    FileInputStream fis = null;
    try {
    
    
        //1.造文件
        File file = new File("hello.txt");
        //2.造流
        fis = new FileInputStream(file);

        //3.读数据
        byte[] buffer = new byte[5];
        int len;//记录每次读取的字节的个数
        while ((len = fis.read(buffer)) != -1){
    
    
            String str = new String(buffer, 0, len);
            System.out.print(str);
        }
    } catch (IOException e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        //4.关闭流
        try {
    
    
            if (fis != null){
    
    
                fis.close();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

3.5. Use FileInputStream and FileOutputStream to copy images

/**
 * 使用FileInputStream和FileOutputStream实现对图片的复制操作
 */
@Test
public void testFileInputOutputStream(){
    
    
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
    
    
        //1.造文件
        File srcFile = new File("头像.jpg");
        File destFile = new File("头像2.jpg");
        //2.造流
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(destFile);

        //3.复制
        byte[] buffer = new byte[5];
        int len;//记录每次读入的长度
        while ((len = fis.read(buffer)) != -1){
    
    
            fos.write(buffer, 0, len);
        }
        System.out.println("复制成功!");
    } catch (IOException e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        //4.关闭流
        try {
    
    
            if (fis != null){
    
    
                fis.close();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

        try {
    
    
            if (fos != null){
    
    
                fos.close();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

4. One of the processing streams - buffer stream

BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter

Function: Provides stream reading and writing speed

The reason for improving

4.1. Use BufferedInputStream and BufferedOutputStream to copy images

/**
     * 实现非文本文件的复制
     */
    @Test
    public void BufferedStreamTest(){
    
    
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
    
    
            //1.造文件
            File srcFile = new File("头像.jpg");
            File destFile = new File("头像3.jpg");

            //2.造流
            //2.1 造节点流
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1){
    
    
                bos.write(buffer, 0, len);
            }
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            //4.关闭流:要求:先关闭外层的流,再关闭内层的流
            //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可哟自动省略。
            if (bis != null){
    
    
                try {
    
    
                    bis.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }

            if (bos != null){
    
    
                try {
    
    
                    bos.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        }

//        fis.close();
//        fos.close();
    }

4.2. Implement file copying

step:

1.造文件
2.造流
	2.1 造节点流
	2.2 造缓冲流
3.复制的细节:读取、写入
4.关闭流:要求:先关闭外层的流,再关闭内层的流
    说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可哟自动省略。
	/**
     * 实现文件复制的方法
     */
    public void copyFileWithBuffered(String srcPath, String destPath){
    
    
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
    
    
            //1.造文件

            File srcFile = new File(srcPath);
            File destFile = new File(destPath);

            //2.造流
            //2.1 造节点流
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1){
    
    
                bos.write(buffer, 0, len);

                //bos.flush();//刷新缓冲过去
            }
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            //4.关闭流:要求:先关闭外层的流,再关闭内层的流
            //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可哟自动省略。
            if (bis != null){
    
    
                try {
    
    
                    bis.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }

            if (bos != null){
    
    
                try {
    
    
                    bos.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        }

//        fis.close();
//        fos.close();
    }

5. Processing Flow 2—Conversion Flow

1. Conversion stream: Belongs to character stream

​InputStreamReader : Convert a byte input stream into a character input stream—>decode

​OutputStreamReader : Convert a character input stream to a byte output stream—>Encoding

2. Function: Provide conversion between byte stream and character stream

3. Decoding: bytes, byte arrays -> character arrays, strings

​ Encoding: character array, string -> byte, byte array

image.png

5.1. Use of InputStreamReader

/**
     * 此时处理异常的话,仍应该使用try-catch-finally
     * InputStreamReader的使用,实现字节的输入流到字符的输入流的转换
     */
    @Test
    public void test1() throws IOException {
    
    
        FileInputStream fis = new FileInputStream("dbcp.txt");
        //参数2 指明了字符集,具体使用哪个字符集,取决于文件dbcp.txt保存时使用的字符集
        InputStreamReader isr = new InputStreamReader(fis, "utf-8");
//        InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集:UTF-8

        char[] cbuf = new char[20];
        int len;
        while ((len = isr.read(cbuf)) != -1){
    
    
            String str = new String(cbuf, 0, len);
            System.out.print(str);
        }

        isr.close();
    }

5.2. Comprehensive use of InputStreamReader and OutputStreamWriter

/**
 * 综合使用 InputStreamReader 和 OutputStreamWriter
 */
@Test
public void test2() throws Exception{
    
    
    //1. 造文件、造流
    File file1 = new File("dbcp.txt");
    File file2 = new File("dbcp_gbk.txt");

    FileInputStream fis = new FileInputStream(file1);
    FileOutputStream fos = new FileOutputStream(file2);

    InputStreamReader isr = new InputStreamReader(fis, "utf-8");
    OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk");

    //2.读入和写出的过程
    char[] cbuf = new char[20];
    int len;
    while ((len = isr.read(cbuf)) != -1){
    
    
        osw.write(cbuf, 0, len);
    }

    //3.关闭资源
    fis.close();
    fos.close();
}

5.3. Multiple character set encodings

The origin of the coding table

Computers can only recognize binary data, and their early origins are electrical signals. In order to facilitate the application of computers, it can recognize the characters of various countries. The characters of each country are represented by numbers and corresponded one by one to form a table. This is the coding table.

Common coding tables

  1. ASCII: American Standard Information Interchange Code.
    • It can be represented by 7 bits of a byte.
  2. ISO8859-1:Latin code table. European code table.
    • Represented by 8 bits of a byte.
  3. GB2312: China's Chinese encoding table. Up to two bytes encoding all characters
  4. GBK: China's Chinese coding table has been upgraded to incorporate more Chinese characters and symbols. Up to two byte encoding
  5. Unicode: International standard code, integrating all characters currently used by humans. Assign a unique character code to each character. All text is represented by two bytes.
  6. UTF-8: A variable-length encoding method that can use 1-4 bytes to represent a character.
image.png image.png

6. Standard input and output streams

image.png

6.1. Exercises

/**
 * 练习:
 * 从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续
 * 进行输入操作,直至当输入“e”或者“exit”时,退出程序。
 */
public static void main(String[] args) {
    
    
    BufferedReader br = null;
    try {
    
    
        InputStreamReader isr = new InputStreamReader(System.in);
        br = new BufferedReader(isr);
        String data;
        while (true){
    
    
            System.out.println("请输入字符串: ");
            data = br.readLine();
            if ("e".equalsIgnoreCase(data)|| "exit".equalsIgnoreCase(data)){
    
    
                System.out.println("程序结束");
                break;
            }

            String upperCase = data.toUpperCase();
            System.out.println(upperCase);
        }
    } catch (IOException e) {
    
    
        throw new RuntimeException(e);
    } finally {
    
    
        if (br !=  null){
    
    
            try {
    
    
                br.close();
            } catch (IOException e) {
    
    
                throw new RuntimeException(e);
            }
        }
    }
}

7. Print flow

image.png

8. Data flow

image.png

Guess you like

Origin blog.csdn.net/Miss_croal/article/details/132952282