【Java高级编程】IO流

news2024/9/20 16:24:22

在这里插入图片描述

IO流

      • 1、File类的使用
        • 1.1、File类的理解
        • 1.2、File的实例化
        • 1.3、常用方法
      • 2、IO原理及流的分类
        • 2.1、流的分类
        • 2.2、流的体系结构
        • 2.3、输入、输出的标准化过程
      • 3、节点流(或文件流)
        • 3.1、FileReader的使用
        • 3.2、FileWriter的使用
        • 3.3、文本文件的复制
        • 3.4、FileInputStream/FileOutputStream的使用
      • 4、缓冲流
        • 4.1、缓冲流涉及到的类
        • 4.2、作用
        • 4.3、典型代码
      • 5、转换流
        • 5.1、转换流涉及到的类:属于字符流
        • 5.2、作用
        • 5.3、典型实现
        • 5.4、常见的编码表
      • 6、其它的流的使用
        • 6.1、标准输入、输出流
        • 6.2、打印流
        • 6.3、数据流
      • 7、对象流
        • 7.1、对象流
        • 7.2、对象的序列化机制
        • 7.3、序列化代码实现
        • 7.4、反序列化代码实现
        • 7.5、实现序列化的对象所属的类需要满足的条件
      • 8、随机存取文件流
        • 8.1、随机存取文件流
        • 8.2、使用说明
        • 8.3、典型代码
      • 9、NIO.2中Path、Paths、Files类的使用
        • 9.1、NIO的使用说明
        • 9.2、Path的使用
        • 9.3、Files工具类

1、File类的使用

1.1、File类的理解

  • File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)
  • File类声明在java.io包下
  • File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
  • 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”

1.2、File的实例化

  • 常见构造器
    • File(String filePath)
    • File(String parentPath, String childPath)
    • File(File parentFile, String childPath)
  • 路径的分类
    • 相对路径:相较于某个路径下,指明的路径
    • 绝对路径:包含盘符在内的文件或文件目录的路径
  • 路径分隔符
    • public static final String separator:根据操作系统,动态的提供分隔符

1.3、常用方法

  • File类的获取功能
    • 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数组
  • File类的重命名功能
    • public boolean renameTo(File dest):把文件重命名为指定的文件路径。要想保证返回true,需要源文件在硬盘中存在,且目标文件不能在硬盘中存在
  • File类的判断功能
    • public boolean isDirectory():判断是否是文件目录
    • public boolean isFile():判断是否是文件
    • public boolean exists():判断是否存在
    • public boolean canRead():判断是否可读
    • public boolean canWrite():判断是否可写
    • public boolean isHidden():判断是否隐藏
  • File类的创建功能
    • public boolean creatNewFile():创建文件。若文件存在,则不创建,返回false
    • public boolean mkdir():创建文件目录。如果文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
    • public boolean mkdirs():创建文件目录。如果上层文件目录不存在,一并创建
  • File类的删除功能
    • public boolean delete():删除文件或文件夹。要删除一个文件目录,请注意该文件目录内不能包含文件或文件目录

2、IO原理及流的分类

2.1、流的分类

  • 按操作数据单位不同分为:字节流、字符流
  • 按数据流的流向不同分为:输入流、输出流
  • 按流的角色的不同分为:节点流、处理流

2.2、流的体系结构

分类字节输入流字节输出流字符输入流字符输出流
抽象基类InputStreamOutputStreamReaderWriter
访问文件FileInputStreamFileOutputStreamFileReaderFileWriter
访问数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
访问管道PipedInputStreamPipedOutputStreamPipedReaderPipedWriter
访问字符串StringReaderStringWriter
缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
转换流InputStreamReaderOutputStreamWriter
对象流ObjectInputStreamObjectOutputStream
FilterInputStreamFilterOutputStreamFilterReaderFilterWriter
打印流PrintStreamPrintWriter
推回输入流PushbackInputStreamPushbackReader
特殊流DataInputStreamDataOutputStream

2.3、输入、输出的标准化过程

  • 输入过程
    • 创建File类的对象,指明读取的数据的来源。(要求此文件一定要存在)
    • 创建相应的输入流,将File类的对象作为参数,传入流的构造器中
    • 具体的读入过程
    • 关闭流资源
  • 输出过程
    • 创建File类的对象,指明写出的数据的位置。(不要求此文件一定要存在)
    • 创建相应的输出流,将File类的对象作为参数,传入流的构造器中
    • 具体的写出过程
    • 关闭流资源

说明:程序中出现的异常需要使用try-catch-finally处理

3、节点流(或文件流)

3.1、FileReader的使用

  • read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
  • 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
  • 读入的文件一定要存在,否则就会报FileNotFoundException
@Test
public void testFileReader1 () {
    FileReader fr = null;
    try {
        // 1、File类的实例化
        File file = new File("hello.txt");

        // 2、FileReader流的实例化
        fr = new FileReader(file);

        // 3、读入的操作
        // read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾则返回-1
        char[] cbuf = new char[5];
        int len;
        while ((len = fr.read(cbuf)) != -1) {
            String str = new String(cbuf, 0, len);
            System.out.println(str);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fr != null) {
            // 4、关闭资源
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.2、FileWriter的使用

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

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

        // 3、写出的操作
        fw.write("I have a dream!\n");
        fw.write("you need to have a dream!");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4、流资源的关闭
        if (fw != null) {
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.3、文本文件的复制

@Test
public void testFileReaderFileWriter () {
    FileReader fr = null;
    FileWriter fw = 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) {
        e.printStackTrace();
    } finally {
        // 4、关闭流资源
        if (fw != null) {
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fr != null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.4、FileInputStream/FileOutputStream的使用

  • 对于文本文件(.txt, .java, .c, .cpp),使用字符流处理
  • 对于非文本文件(.jpg, .mp3, .mp4, .avi, .doc, .ppt,…),使用字节流处理
/**
  * 实现对图片的复制操作
  */
@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);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4、关闭流
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

说明:
IDEA中:如果大家开发使用JUnit中的单元测试方法测试,相对路径即为当前Module下。如果使用main()测试,相对路径即为当前的Project下。
Eclipse中:不管使用单元测试方法还是使用main()测试,相对路径都是当前的Project下

4、缓冲流

4.1、缓冲流涉及到的类

  • BufferedInputStream
  • BufferedOutputSteam
  • BufferedReader
  • BufferedWriter

4.2、作用

  • 提高流的读取、写入的速度。
  • 提高读写速度的原因:内部提供了一个缓冲区。默认情况下是8kb
public class BufferedInputStream extends FilterInputStream {

    private static int DEFAULT_BUFFER_SIZE = 8192;

}

4.3、典型代码

  • 使用BufferedInputStream和BufferedOutputStream:处理非文本文件
@Test
public void copyFileWithBuffered(String srcPath, String destPath) {
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        // 1、造文件
        File srcFile = new File(srcPath);
        File destFile = new File(destPath);
        // 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[10];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
            // bos.flush(); //刷新缓冲区
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4、资源关闭
        // 要求:先关闭外层的流,再关闭内层的流
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略
        // fos.close();
        // fis.close();
    }
}
  • 使用BufferedReader和BufferedWriter:处理文本文件
@Test
public void testBufferedReaderBufferedWriter () {
    BufferedReader br = null;
    BufferedWriter bw = null;
    try {
        // 创建文件和相应的流
        br = new BufferedReader(new FileReader(new File("dbcp.txt")));
        bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));

        // 读写操作
        // 方式一:使用char[]数组
        // char[] cbuf = new char[1024];
        // int len;
        // while ((len = br.read(cbuf)) != -1) {
        //     bw.write(cbuf, 0, len);
        // }
        // 方式二:使用String
        String data;
        while ((data = br.readLine()) != null) {
            // 方法一:
            // bw.write(data + "\n"); // data中不包含换行符
            // 方法二:
            bw.write(data);
            bw.newLine(); // 提供换行的操作
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

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

}

5、转换流

5.1、转换流涉及到的类:属于字符流

  • InputStreamReader:将一个字节的输入流转换为字符的输入流
    • 解码:字节、字节数组 —> 字符数组、字符串
  • OutputStreamWriter:将一个字符的输出流转换为字节的输出流
    • 编码:字符数组、字符串 —> 字节、字节数组

说明:编码决定了解码的方式

5.2、作用

  • 提供字节流与字符流之间的转换

5.3、典型实现

  • 文件编码的方式(比如:GBK),决定了解析时使用的字符集(也只能是GBK)
@Test
public void test2 () {
    InputStreamReader isr = null;
    OutputStreamWriter osw = null;
    try {
        // 1、造文件、造流
        File file1 = new File("dbcp.txt");
        File file2 = new File("dbcp_gbk.txt");

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

        // isr = new InputStreamReader(fis); // 使用系统默认的字符集
        isr = new InputStreamReader(fis, "utf-8");
        osw = new OutputStreamWriter(fos, "gbk");

        // 2、读写过程
        char[] cbuf = new char[20];
        int len;
        while ((len = isr.read(cbuf)) != -1) {
            osw.write(cbuf, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 3、关闭资源
        if (isr != null) {
            try {
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

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

5.4、常见的编码表

  • ASCII:美国标准信息交换码。用一个字节的7位可以表示。
  • ISO8859-1:拉丁码、欧洲码表。用一个字节的8位表示
  • GB2312:中国的中文编码表。最多两个字节编码所有字符
  • GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
  • Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。
  • UTF-8:变长的编码方法,可用1-4个字节来表示一个字符。

6、其它的流的使用

6.1、标准输入、输出流

  • System.in:标准的输入流,默认从键盘输入
  • System.out:标准的输出流,默认从控制台输出
  • 修改默认的输入和输出行为
    • System类的setIn(InputStream is)/setOut(PrintStream ps)方式重新指定输入和输出的流

6.2、打印流

  • PrintStream和PrintWriter
  • 提供了一些列重载的print()和println()方法,用于多种数据类型的输出
  • System.out返回的是PrintStream的实例

6.3、数据流

  • DataInputStream和DataOutputStream
  • 用于读取或写出基本数据类型的变量或字符串
@Test
public void test3() {
    DataOutputStream dos = null;
    try {
        dos = new DataOutputStream(new FileOutputStream("data.txt"));

        dos.writeUTF("刘建辰");
        dos.flush(); // 刷新操作,将内存中的数据写入文件
        dos.writeInt(23);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dos != null) {
            try {
                dos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
  * 注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致
  */
@Test
public void test4() {
    DataInputStream dis = null;
    try {
        dis = new DataInputStream(new FileInputStream("data.txt"));

        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        System.out.println(name);
        System.out.println(age);
        System.out.println(isMale);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dis != null) {
            try {
                dis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

7、对象流

7.1、对象流

  • ObjectInputStream:内存中的对象 —> 存储中的文件、通过网络传输出去(序列化过程)
  • ObjectOutputSteam:存储中的文件、通过网络接受过来 —> 内存中的对象(反序列化过程)

7.2、对象的序列化机制

  • 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。
  • 当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

7.3、序列化代码实现

@Test
public void testObjectOutputSteam () {
    ObjectOutputStream oos = null;
    try {
        // 1、造流
        oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
        // 2、读写过程
        oos.writeObject(new String("我爱北京天安门"));
        oos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 3、关闭资源
        if (oos != null) {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

7.4、反序列化代码实现

@Test
public void testObjectInputSteam () {
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream("object.dat"));

        Object obj = ois.readObject();
        String str = (String) obj;

        System.out.println(str);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ois != null) {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

7.5、实现序列化的对象所属的类需要满足的条件

  • 需要实现接口:Serializable
  • 当前类提供一个全局常量:serialVersionUID
  • 除了当前类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)

补充:ObjectOutputSteam和ObjectInputStream不能序列化static和transient修饰的成员变量

8、随机存取文件流

8.1、随机存取文件流

  • RandomAccessFile

8.2、使用说明

  • RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口
  • RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
  • 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。如果写出到的文件存在,则会对原文件内容进行覆盖。(默认情况下,从头覆盖)
  • 可以通过相关的操作,实现RandomAccessFile“插入”数据的效果。seek(int pos)

8.3、典型代码

/**
 * 实现复制功能
 */
@Test
public void test1 () {
    RandomAccessFile raf1 = null;
    RandomAccessFile raf2 = null;
    try {
        // 1、造流
        raf1 = new RandomAccessFile(new File("爱情与友情.jpg"), "r");
        raf2 = new RandomAccessFile(new File("爱情与友情1.jpg"), "rw");
        // 2、读写过程
        byte[] buffer = new byte[1024];
        int len;
        while ((len = raf1.read(buffer)) != -1) {
            raf2.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 3、关闭资源
        if (raf1 != null) {
            try {
                raf1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (raf2 != null) {
            try {
                raf2.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
/**
 * 使用RandomAccessFile实现数据的插入效果
 */
@Test
public void test3 () {
    RandomAccessFile raf1 = null;
    try {
        raf1 = new RandomAccessFile("hello.txt", "rw");

        raf1.seek(3); // 将指针调到角标为3的位置
        // 保存指针3后面的所有数据到StringBuilder中
        StringBuilder buildr = new StringBuilder((int) new File("hello.txt").length());
        byte[] buffer = new byte[20];
        int len;
        while ((len = raf1.read(buffer)) != -1) {
            buildr.append(new String(buffer, 0, len));
        }

        // 调回指针,写入“xyz”
        raf1.seek(3);
        raf1.write("xyz".getBytes());

        // 将StringBuilder中的数据写入到文件中
        raf1.write(buildr.toString().getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (raf1 != null) {
            try {
                raf1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

9、NIO.2中Path、Paths、Files类的使用

9.1、NIO的使用说明

  • Java NIO(New IO, Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO API。
  • NIO与原来的IO同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作
  • NIO将以更高效的方式进行文件的读写操作
  • 随着JDK 7的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为NIO.2

9.2、Path的使用

  • Path替换原有的File类
  • Paths类提供了静态get()方法用来获取Path对象:
    • static Path get(String first, String … more):用于将多个字符串串连成路径
    • static Path get(URI uri):返回指定uri对应的Parh路径
  • 常用方法:
    • String toString():返回调用Path对象的字符串表示形式
    • boolean startsWith(String path):判断是否以path路径开始
    • boolean endsWith(String path):判断是否以path路径结束
    • boolean isAbsolute():判断是否是绝对路径
    • Path getParent():返回path对象包含整个路径,不包含Path对象指定的文件路径
    • Path getRoot():返回调用Path对象的根路径
    • Path getFileName():返回与调用Path对象关联的文件名
    • int getNameCount():返回Path根目录后面元素的数量
    • Path getName(int idx):返回指定索引位置idx的路径名称
    • Path toAbsolutePath():作为绝对路径返回调用Path对象
    • Path resolve(Path p):合并两个路径,返回合并后的路径对应的Path对象
    • File toFile():将Path转换为File类的对象

9.3、Files工具类

  • 作用:操作文件或文件目录的工具类
  • 常用方法:
    • Path copy(Path src, Path dest, CopyOption … how):文件的复制
    • Path createDirectory(Path path, FileAttribute<?> … attr):创建一个目录
    • Path createFile(Path path, FileAttribute<?> … arr):创建一个文件
    • void delete(Path path):删除一个文件/目录,如果不存在,执行报错
    • void deleteIfExists(Path path):Path对应的文件/目录如果存在,执行删除
    • Path move(Path src, Path dest, CopyOption … how):将src移动到dest位置
    • long size(Path path):返回指定文件的大小
  • 用于判断:
    • boolean exists(Path path, LinkOption … opts):判断文件是否存在
    • boolean isDirectory(Path path, LinkOption … opts):判断是否是目录
    • boolean isRegularFile(Path path, LinkOption … opts):判断是否是文件
    • boolean isHidden(Path path):判断是否是隐藏文件
    • boolean isReadable(Path path):判断文件是否可读
    • boolean isWritable(Path path):判断文件是否可写
    • boolean notExists(Path path, LinkOption … opts):判断文件是否不存在
  • 用于操作内存
    • SeekableByteChannel newByteChannel(Path path, OpenOption … how):获取与指定文件的连接,how指定打开方式
    • DirectoryStream<Path> newDirectoryStream(Path path):打开path指定的目录
    • InputStream newInputStream(Path path, OpenOption … how):获取InputStream对象
    • OutputStream newOutputStream(Path path, OpenOption … how):获取OutputStream对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/698261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3学习(一)创建项目集成ElementPlus

一、创建vue项目 软件安装&#xff1a;nodejs16 https://nodejs.org/download/release/v16.20.0/ 将npm设置为淘宝镜像&#xff1a; npm config set registry https://registry.npm.taobao.org 开始创建vue3项目 npm init vuelatest npm install npm run dev Eleement-Plus …

【python】dlib人脸识别初步

文章目录 安装与初步使用HOG算法人脸识别CNN人脸识别CNN车辆识别 安装与初步使用 dlib也是从C转过来的Python模块&#xff0c;正常安装非常痛苦&#xff0c;需要下载cmake还有boost&#xff0c;所以这里推荐用conda来安装&#xff0c;一行代码轻松搞定 conda install -c cond…

Rust简介

Rust简介 为什么要用Rust与其他语言比较Rust 特别擅长的领域Rust 与 FireFoxRust 的用户和案例![在这里插入图片描述](https://img-blog.csdnimg.cn/b1e0a39c53ba45d1a3c93d0dd73408fe.png)Rust 优缺点 ref: https://www.bilibili.com/video/BV1hp4y1k7SV 为什么要用Rust 与其…

构建便捷高效的宠物医疗预约服务平台:基于Spring Boot的实现

本文介绍了基于Spring Boot的宠物医疗预约服务平台的设计与实现。通过使用Spring Boot框架和相关技术,我们建立了一个功能丰富的平台,为宠物主人提供了便捷的宠物医疗预约服务。本文将详细介绍平台的架构设计和关键功能模块,并提供相关代码示例以展示技术实现的深度。 宠物…

内网渗透解析

1|0一、前言 阅读本文前需要先搞懂NAT、PAT、端口映射几个概念&#xff0c;内网宽带中的主机可以访问公网宽带主机&#xff0c;反之不可以访问&#xff1b;公网宽带主机可以和公网宽带主机双向访问&#xff1b;内网宽带中的主机和内网宽带中的主机互相无法访问。那么内网宽带中…

前端JavaScript入门-day05

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 对象 1. 对象是什么 对象&#xff08;object&#xff09;&#xff1a;JavaScript里的一种数据类型 可以理解为是一…

Elasticsearch和Kibana的安装

Elasticsearch和Lucene的关系 Elasticsearch是一个高度可扩展的、开源的、基于 Lucene 的全文搜索和分析引擎。它允许您快速&#xff0c;近实时地存储&#xff0c;搜索和分析大量数据&#xff0c;并支持多租户。 Elasticsearch也使用Java开发并使用 Lucene 作为其核心来实现所…

Docker Compose基础与实战

一、是什么 Compose 项目是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的快速编排。 二、能做什么 Compose允许用户通过一个单独的docker-compose.yml模板文件&#xff08;YAML 格式&#xff09;来定义一组相关联的应用容器为一个项目&#xff08;project&…

单链表的简介与实现(Java)

一、前言 线性结构的链式存储是用若干地址分散的存储单元存储数据元素&#xff0c;逻辑上相邻的两个数据元素在物理位置上并不一定相邻&#xff0c;必须采用附加信息来表示数据元素之间的顺序关系。因此存储一个数据元素的数据单元至少包含两部分------数据域和地址域 上述的结…

java简易计算器的设计

简易计算器的设计 1.1实训内容 模仿Windows自带的标准版计算器&#xff0c;设计并用Java语言实现简易的计算器&#xff08;根据自己的能力&#xff0c;可以适当地增加或删除部分功能&#xff09;。 最低要求&#xff1a; 计算器运行界面如下图所示&#xff0c;包含二个文本框…

Android Binder通信原理(七):java 下的C-S

源码基于&#xff1a;Android R 0. 前言 在之前的几篇博文中&#xff0c;对Android binder 的通信原理进行的深入的剖析&#xff0c;这些博文包括&#xff1a;binder 简介、servicemanager启动、service注册、service获取、Java 端的service 注册和获取。 在前一文中&#xf…

PostgreSQL处理JSON数据

源&#xff1a;https://blog.csdn.net/c_zyer/article/details/130968257?ops_request_misc&request_id&biz_id102&utm_termPostgreSQL%20%E7%9A%84JSON%20%E5%A4%84%E7%90%86&utm_mediumdistribute.pc_search_result.none-task-blog-2allsobaiduweb~default-…

pgsql:纵列字段转为横列字段

问题&#xff1a; 想要将查询出来的数据纵列字段转为横列字段。如以下是24小时内每个小时的数据表&#xff1a; SELECT deviceid,press_avg, hh FROM site_data 想要转换后的效果如下&#xff0c;将24小时内所有数据横向展示&#xff1a; 解决方案&#xff1a; 实现的sql查询…

Spring事务的介绍和使用

目录 一、Spring事务作用 二、代码实现 三、Spring事务相关配置 1、事务配置 2、事务传播行为 一、Spring事务作用 事务作用&#xff1a;在数据层保障一系列的数据库操作同成功同失败 Spring事务作用&#xff1a;在数据层或业务层保障一系列的数据库操作同成功同失败 二、…

分散输入和集中输出(Scatter-Gather I/O):readv()和writev()

readv()和writev()系统调用分别实现了分散输入和集中输出的功能。 NAMEreadv, writev, preadv, pwritev - read or write data into multiple buffersSYNOPSIS#include <sys/uio.h>ssize_t readv(int fd, const struct iovec *iov, int iovcnt);ssize_t writev(int fd, c…

蓝桥杯专题-试题版-【数字游戏】【城市建设】【最大子阵】【蚂蚁感冒】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

数字人解决方案——基于真人视频的三维重建数字人源码与训练方法

前言 1.真人视频三维重建数字人源码是基于NeRF改进的RAD-NeRF&#xff0c;NeRF&#xff08;Neural Radiance Fields&#xff09;是最早在2020年ECCV会议上的Best Paper&#xff0c;其将隐式表达推上了一个新的高度&#xff0c;仅用 2D 的 posed images 作为监督&#xff0c;即…

MongoDB存储引擎

1、前言 存储引擎是数据库的组成部分&#xff0c;负责管理数据存储。 MongoDB支持的以下存储引擎&#xff1a; 存储引擎 描述 WiredTiger存储引擎 从MongoDB 3.2开始默认的存储引擎&#xff0c;新的版本MongoDB推荐使用WiredTiger存储引擎。 MMAPv1存储引擎 MMAPv1是Mon…

微信小程序使用vant组件样式未生效解决办法

1.删除小程序自带的样式 首先在app.json里面删除这一行 2.清除缓存 重新编译 3.重新构建npm 重新编译 在工具里面

nginx之rewrite

一、Rewrite跳转的场景二、Rewrite跳转实现三、Rewrite实际场景四、常用的 Nginx 正则表达式五、Rewrite命令、语法格式六、location的分类七、location的优先级八、rewrite与location的区别九、rewrite示例9.1 基于域名的跳转9.2 基于客户端 IP 访问跳转9.3 基于旧域名跳转到新…