看看Java里面的IO

地址

IO流

intput:输入流,从网络种读取文件到内存,磁盘里面读取文件到内存。

output:输出流,从内存里面读取文件显示在网络上面,内存的数据写到文件上面。

字节流

以byte为最小单位。

intputStream 输入字节流

outputStream 输出字节流

字符流

以char字符的方式去读写

如果文件是以文本的方式存在,用字符流方便

reader 读

writer 写

同步&异步

IO同步

这个CPU在等待现在正在进行的IO,必须等现在进行的IO执行完毕了。在去执行下一个IO。

IO操作的时候,必须等待数据返回!才能执行下面的代码。

IO异步

IO操作的时候,不需要等待数据返回!就可以执行下面的代码

在java.io里面都是同步IO

在java.nio里面都是异步IO

File 文件对象

package com.hu.io_;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

public class FileDome {
    public static void main(String[] args) throws IOException{
        /*
        * 创建一个file里面可以放入绝对路径和相对路径
        * 绝对路径:以根目录为开头的例如:C:\\a\\a.txt
        * 相对路径:取出掉绝对路径的目录就是相当路径例如:a\\a.txt
        *
        * File:有三种表示路径的方式
        * file.getPath(): 返回构造器里面的路径
        * file.getAbsolutePath(): 返回绝对路径
        * file.getCanonicalPath(): 返回规范路径
        *规范路径就是:把.和.. 当前级和返回上一级给表现出来。
        *
        * File是一个文件对象,他也可以表示一个目录对象。
        * isFile() 判断是否是一个文件
        * isDirectory() 判断是否是一个目录
        * 用File对象获取到一个文件时,还可以进一步判断文件的权限和大小:
            boolean canRead():是否可读;
            boolean canWrite():是否可写;
            boolean canExecute():是否可执行;
            long length():文件字节大小。

          创建和删除文件:
           file.createNewFile();
           file.delete();
           * Java里面提供了一个创建临时文件的
           * File.createTempFile("tmp-", ".txt"); // 提供临时文件的前缀和后缀
             deleteOnExit(); // JVM退出时自动删除

           遍历文件或目录
           当File对象表示一个目录时,可以使用list()和listFiles()列出目录下的文件和子目录名
            File[] files = file.listFiles(); 返回当前目录下的所有文件
            * File[] fs2 = file.listFiles(new FilenameFilter() { // 仅列出.exe文件
            public boolean accept(File dir, String name) {
                return name.endsWith(".txt"); // 返回true表示接受该文件
            }
        });返回当前目录下面的txt后缀名的文件
        * 如何创建一个目录
            File file = new File("C:\\ABC");
        if(file.mkdirs()){
            System.out.println("创建成功!");
        }
        * 如何删除这个目录
        *
        * */
        File file = new File("C:\\ABC");
        if(file.delete()){
            System.out.println("cs成功!");
        }
//        File file = new File("D:\\User\\hupenglong.UCO\\Desktop\\demoGit");
//
//        File[] files = file.listFiles();
//        printFiles(files);
//        File[] fs2 = file.listFiles(new FilenameFilter() { // 仅列出.exe文件
//            public boolean accept(File dir, String name) {
//                return name.endsWith(".txt"); // 返回true表示接受该文件
//            }
//        });
//        printFiles(fs2);
//        File f = File.createTempFile("abc", ".txt");
//
//        f.deleteOnExit();
//        System.out.println(f.getAbsolutePath());
//        File file = new File("..");
//        System.out.println(file.getPath());
//        System.out.println(file.getAbsolutePath());
//        System.out.println(file.getCanonicalPath());
//        File file = new File("D:\\User\\hupenglong.UCO\\Desktop\\demoGit\\wd.txt");
//        System.out.println(file.isFile());//T
//        System.out.println(file.isDirectory());//F
        //         File file = new File("D:\\User\\hupenglong.UCO\\Desktop\\demoGit\\wd");
//          file.createNewFile();
//          file.delete();

        //System.out.println(File.separator); // 根据当前平台打印"\"或"/"





    }

    static void printFiles(File[] files) {
        System.out.println("==========");
        if (files != null) {
            for (File f : files) {
                System.out.println(f);
            }
        }
        System.out.println("==========");
    }
}
<di> </di>

遍历一个文件夹下面所有的文件

public void selectFile(File file){
    Files[] fs = file.listFiles();
    for(int i = 0; i < fs.length;i++){
        if(fs[i].isDirectory()){
            selectFile(fs[i]);
        }else{
            System.out.println(fs);
        }
    }
}

InputStream

InputStream是一个抽象类,是输入IO里面的基类。

这一个read方法非常重要

public abstract int read() throws IOException;

去读取数据,读数据的下一行并且返回一个【0~255】的数字,如果读带最后一行返回-1

根据以上案例如何去读一个文件

一直去读嘛,然后返回值是-1停止。记得关闭资源

Java7的引入的语法

//用try ... finally来编写上述代码会感觉比较复杂,更好的写法是利用Java 7引入的新的try(resource)的语法,只需要编写try语句,让编译器自动为我们关闭资源。推荐的写法如下:
public void readFile() throws IOException {
    try (InputStream input = new FileInputStream("src/readme.txt")) {
        int n;
        while ((n = input.read()) != -1) {
            System.out.println(n);
        }
    } // 编译器在此自动为我们写入finally并调用close()
}
//实际上,编译器并不会特别地为InputStream加上自动关闭。编译器只看try(resource = ...)中的对象是否实现了java.lang.AutoCloseable接口,如果实现了,就自动加上finally语句并调用close()方法。InputStream和OutputStream都实现了这个接口,因此,都可以用在try(resource)中。

缓冲

一个一个读取太慢了。我们可以先读取一部分放在一个容器里面

就是一次性读取多个字节,InputStream里面提供两个重载的方法

  • int read(byte[] b):读取若干字节并填充到byte[]数组,返回读取的字节数
  • int read(byte[] b, int off, int len):指定byte[]数组的偏移量和最大填充数

阻塞

我们的是同步IO的,所以在读的时候不知道要等多久

OutputStream

是基本输出IO,他的输出差不多

public abstract void write(int b) throws IOException;

虽然是int类型的参数,不过他只写入一个字节的。

这里面有一个fluch(),和缓存差不多就是写的时候一个一个写太慢了。先写在一个容器里面在一次性写出去。

我们来实现一下文件的复制

基本原理就是读一个文件,同时去写一个文件。

package com.hu.io_;

import java.io.*;

public class Text3 {
    public static void main(String[] args) {
        InputStream input = null;
        OutputStream output = null;
        try{
            input = new FileInputStream("D:\\User\\hupenglong.UCO\\Desktop\\t\\a.txt");
             output = new FileOutputStream("D:\\User\\hupenglong.UCO\\Desktop\\t\\b.txt");
            while(true){
                int n =  input.read();
                output.write(n);
                if(n == -1){
                    break;
                }
                System.out.println(n);
            }

        }catch(IOException e){
            System.out.println(e);
        }
        finally{
            try {
                input.close();
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

Filter 模式 这就是装饰器模式

FileinputStream 如果给他添加一个缓存

FileinputStream 如果给他添加一个加密

FileinputStream 如果给他添加一个签名

我们都需要添加一个类去继承FileinputStream,这种子类太多了非常麻烦!

但是我们可以子类引用指向父类。

InputStream in = new FileInputStream("test.gz");

InputStream in = new 其他的子类,

通过少量的类,来实现工作功能组合

我们编写一个自己这对于IO流的功能的

public class Main {
    public static void main(String[] args) throws IOException {
        byte[] data = "hello, world!".getBytes("UTF-8");
        try (CountInputStream input = new CountInputStream(new ByteArrayInputStream(data))) {
            int n;
            while ((n = input.read()) != -1) {
                System.out.println((char)n);
            }
            System.out.println("Total read " + input.getBytesRead() + " bytes");
        }
    }
}

//CountInputStream,它的作用是对输入的字节进行计数:
class CountInputStream extends FilterInputStream {
    private int count = 0;

    CountInputStream(InputStream in) {
        super(in);
    }

    public int getBytesRead() {
        return this.count;
    }

    public int read() throws IOException {
        int n = in.read();
        if (n != -1) {
            this.count ++;
        }
        return n;
    }

    public int read(byte[] b, int off, int len) throws IOException {
        int n = in.read(b, off, len);
        if (n != -1) {
            this.count += n;
        }
        return n;
    }
}

序列化

序列化,就是把Java对象变成为一个byte[] 二进制数据,然后这样就方便在网络上传输了

一个类要实现这种操作,必须实现Serializable 接口

ClassPath路径

我们在读取一个文件的时候要根据文件的路径去读,但是操作系统不同读取的文件路径就是不同的这样就很麻烦






全部评论
IO这个太重要了
点赞 回复 分享
发布于 2022-08-16 21:21

相关推荐

勤奋努力的椰子这就开摆:美团骑手在美团工作没毛病
投递美团等公司10个岗位
点赞 评论 收藏
分享
挣K存W养DOG:他真的很中意你,为什么不回他
点赞 评论 收藏
分享
评论
2
1
分享
牛客网
牛客企业服务