Java 基础 IO

1 Java IO流

目录

  • File类的使用
  • IO流原理以及流的分类
  • 文件流
  • 缓冲流
  • 转换流
  • 其他流
    • 标准输入,输出流
    • 打印流
    • 数据流
    • 对象流
  • 随机存储文件流
  • NIO中 Path Paths Files 类的使用

代码Gitee 地址 day08~day10 https://gitee.com/nutxi/javabase
1 File的相关解释

  • File是对文件和文件目录的一种抽象表示

  • File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。

    如果需要访问文件内容本身,则需要使用输入/输出流

  • 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对 象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。

    File 对象可以作为参数传递给流的构造器

2 File类的创建

public File(String pathname)

可以是绝对路径或者相对路径

  • 相对路径,单元测试 中IDEA中是相对与当前模块目录下 main方法中说相对于工程目录下
  • 绝对路径 带盘符

路径分隔符问题

路径中的每级目录之间用一个路径分隔符隔开

路径分隔符和系统有关

  • windows和DOS系统默认使用“\”来表示
  • UNIX和URL使用“/”来表示

Java程序支持跨平台运行,为了支持不同平台的路径分隔符,File类提供了一个常量,public static final String separator。根据操作系统,动态的提供分隔符

 这里的\\ 为了转义
File file1 = new File("d:\\atguigu\\info.txt");
File file2 = new File("d:" + File.separator + "atguigu" + File.separator + "info.txt");
File file3 = new File("d:/atguigu");
  • public File(String parent,String child)
File file1 = new File("d:\\atguigu","info.txt");
  • public File(File parent,String child)

    根据一个父File对象和子文件路径创建File对象

**3 File类的常用方法 **(了解即可)

  • 获取功能

    public String getAbsolutePath():获取绝对路径

​ public String getName() :获取名称

​ public long lastModified() :获取最后一次的修改时间,毫秒值

​ public long length() :获取文件长度(即:字节数)。不能获取目录的长度

File为目录时候

  • public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
  • public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组

如果 File1.renameTo(File dest) 返回true ,要求File1存在,dest不存在

  • public boolean renameTo(File dest):把文件重命名为指定的文件路径

File的判断功能

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

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

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

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

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

  • public boolean isHidden() :判断是否隐藏

File类的创建功能

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

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

    如果此文件目录的上层目录不存在,也不创建

    public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建

注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目

路径下 既相对路径

File的删除功能

  • public boolean delete():删除文件或者文件夹

​ Java中的删除不走回收站

​ 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录

当硬盘中真有一个真实的文件或目录存在时,创建File对象时,各个属性会显式赋值。

当硬盘中没有真实的文件或目录对应时,那么创建对象时,除了指定的目录和路径之外,其他的属性都是取成员变量的默认值。

2 IO流的原理以及 流的分类 *

I/O技术是非常实用的技术,用于处理设备之间的数据传输

java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据

输入 input 读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。

输出 output:将程序(内存)数据输出到磁盘、光盘等存储设 备中

IO流的分类

  1. 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
    • 字节流 适合读取非文本数据,如图像,视频等
    • 字符流 适合读取文本数据

2 . 按数据流的流向不同分为:输入流,输出流

3 按流的角色的不同分为:节点流,处理流

节点流之间作用文件上,文件相当于一个节点,处理流基于节点流创建
在这里插入图片描述
流的体系结构
在这里插入图片描述

所有的流基本都是他们派生出来的子类,由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

在这里插入图片描述
蓝色表示重点,要关注的
学习节点流,主要关注如何实现输入和输出操作,
学习处理流,主要关注如何实现拓展的功能,其输入于输出和节点流都是差不多的

3 文件流 *

Reader 流

  • 每次读取单个字符
 @Test
    public  void  readTest(){
        File file = new File("hello.txt");
        System.out.println(file.getAbsolutePath());
        FileReader  fileReader = null;
        try {
          fileReader = new FileReader(file);

            int data;
            while ((data = fileReader.read()) !=-1){
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
           if (file!=null)
               try {
                   fileReader.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }

        }

    }
  • read 方法每次调用读入一个字节,如果读到文件末尾则返回-1
  • 异常的处理,JVM只回收java堆里面的对象空间,对于其他连接如数据库连接,输入输出流,Socket连接无能为力
  • 因此需要显示关闭输入流,并且注意在文件不为空的情况下关闭

输入输出流的基本模式如下

1 File 类的实例化

2 流的实例化


3 读入/写出操作

4 资源关闭

后面主要是2,3不同
  • 每次读取多个字符
 @Test
    public  void readBuffer(){
        File file = new File("hello.txt");
        System.out.println(file.getAbsolutePath());
        FileReader  fileReader = null;
        try {
            fileReader = new FileReader(file);
            //字符流 因此构建字符数组

            char[] cbuf = new char[5];
            int len= 0;
            //public int read(char[] cbuf) 读取cbuf 长度的字符,返回每次读取字符的长度,如果到文件末尾则返回-1
            while ((len = fileReader.read(cbuf)) !=-1){
                /* 方式一
                for (int i = 0; i <len ; i++) {
                    System.out.print(cbuf[i]);
                }

                 */
//                方式二 ,使用String构造函数

                String s = new String(cbuf, 0, len);
                System.out.print(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file!=null)
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

        }
  • cbuf 数组每次读取的原理

以 helloworld123 举例

  • 第一次 hello
  • 第二次 world
  • 第三次 123ld
  • 第四次 返回-1

既将读取的字符,覆盖原有数组中 的数据

  • 有两种方式 读取cbuf数组中的数据
    • 循环
    • String

2 FileWriter 写入文件

  @Test
    public void wirte() throws IOException {
        File file = new File("hello1.txt");

        FileWriter fileWriter = new FileWriter(file,true);

        fileWriter.write("you need to have a dream\n");
        fileWriter.write("we have a dream");

        fileWriter.close();
    }
  • 输出操作 ,对应的file 可以不存在,输出过程中会自动创建
  • 如果文件存在, public FileWriter(File file, boolean append)
    • 如果append 为true 则是在原有文件后追加
    • 默认为false ,覆盖原有文件夹的内容

3 FileRead 和 FileWirter 实现文本复制

套路

1 创建File类的对象 ,指明读入和写出文件
2 创建输入流和输出流的对象
3 数据的读入和写出操作
4 关闭资源
  @Test
    public  void  copyTest(){
        File src = new File("hello.txt");
        File desc = new File("copy.txt");
        FileReader fileReader = null;
        FileWriter fileWriter = null;
        //1 创建需要文件对象,要写入和写出的
        try {
            //2 创建流
           fileReader = new FileReader(src);
           fileWriter  = new FileWriter(desc);

            //3 读取操作
            char[] cbuf = new char[5];
            int len=0;
            while ((len = fileReader.read(cbuf))!=-1){
                fileWriter.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4 关闭流
            if (src != null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (desc != null){
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }



        }


    }
  • 对于文本文件(.txt,java.c…),使用字符流处理,字节流会产生乱码问题
  • 对于非文本文件(.jpg, .mp3, .mp4,.avi,.doc),使用字节流处理

4 FileInputStream FileOutPutStream

字节流基本操作和上面字符流一样,只是字符数组换成字节数组

1 实现图片复制

  @Test
    public void  cptyimg(){

        File src = new File("girl.jpg");
        File dest = new File("gril.jpg");

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(src);
            fos = new FileOutputStream(dest);

            int len=0;
            byte[] buf = new byte[10];
            while ((len = fis.read(buf))!=-1){
                fos.write(buf,0,len);
            }

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

            if (src!=null)
                try {
                    System.out.println("图片复制成功");
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            if (dest !=null)
                System.out.println("图片复制成功2");
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

    }

4 缓冲流 提高文件读写效率 *

1 BufferedInputStream BufferedOutputStream

实现非文本复制操作

 @Test
    public void copyimg(){
        //1 创建File 对象
        File srcFile = new File("girl.jpg");
        File destFile = new File("m.jpg");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //2 造流, 节点流-> 缓冲流
            bis  = new BufferedInputStream(new FileInputStream(srcFile));
           bos = new BufferedOutputStream(new FileOutputStream(destFile));


            //3 读取操作
            byte[] cbuf = new byte[5];
            int len=0;
            while ((len= bis.read(cbuf))!=-1){
                bos.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

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

            if (destFile !=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 先创建节点流,再构建缓冲流

  • 使用缓冲流的方法读取数据

  • 关闭流严格上先关闭外层流,再关闭内层流

    但是关闭外层流时候,默认会关闭内层流,因此可以省略

缓冲流提供读写速度的原理

  • BufferedInputStream 和BufferedOutStream 中提供了一个缓冲区,默认大小为8192 ,读取数据时比如一次读取1024个字节,先把数据读取到缓冲区,如果缓冲区满了则自动刷新,将所有数据读取到内存,读出也是一样的

  • bos.flush()可以强制将缓冲区的内容全部写入输出流

1 BufferedReader 和 BufferedWriter 实现文本复制

BufferedReader br = null;
BufferedWriter bw = null;
try {
// 创建缓冲流对象:它是处理流,是对节点流的包装
    br = new BufferedReader(new FileReader("d:\\IOTest\\source.txt"));
    bw = new BufferedWriter(new FileWriter("d:\\IOTest\\dest.txt"));
    String str;
    while ((str = br.readLine()) != null) { // 一次读取字符文本文件的一行字符
    bw.write(str); // 一次写入一行字符串
    bw.newLine(); // 写入行分隔符
}
bw.flush(); // 刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭IO流对象
try {
if (bw != null) {
bw.close(); // 关闭过滤流时,会自动关闭它所包装的底层节点流
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
} }
  • BufferedReader 提供了readline()方法 ,每次读取一行,不会读取换行符,但读到末尾时返回null
  • BufferedWriter 提供了newLine() 写入行分隔符
    练习

1 实现图片加密操作。

2 获取文本上每个字符出现的次数

地址

5 转换流 *

转换流就是转换字节流和字符流

在这里插入图片描述

Java API提供了两个转换流

  • InputStreamReader:将InputStream转换为Reader
  • OutputStreamWriter:将Writer转换为OutputStream

编码与解码

  • 字符串- 字节数组 编码
  • 字节数组- 字符串

要想不出现乱码问题,应该保证编码和解码的规则一样

InputStreamReader

  • 实现将字节的输入流按指定字符集转换为字符的输入流。
  • 构造器

public InputSreamReader(InputStream in,String charsetName) charset 表示字符集,例如

 Reader isr = new InputStreamReader(System.in,”gbk”);
@Test
    public void  changeTest() throws IOException {
        File file = new File("hello.txt");
        FileInputStream fis = new FileInputStream(file);
        //按照系统默认的解码方式进行解码
        InputStreamReader isr = new InputStreamReader(fis);

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

    }

OutputStreamWriter

  • 实现将字符的输出流按指定字符集转换为字节的输出流

  • public OutputSreamWriter(OutputStream out,String charsetName)

实现将UTF-8编码的文本文件,转换为GBK编码的文本文件

 @Test
    public void  charsetChange() throws IOException {
        File file = new File("hello.txt");
        File filel = new File("hello_gbk.txt");

        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(filel);

        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        OutputStreamWriter isw = new OutputStreamWriter(fos,"gbk");


        char[] cbuf = new char[10];
        int len=0;
        while ((len = isr.read(cbuf))!=-1){
            isw.write(cbuf,0,len);
        }
        isr.close();
        isw.close();
    }
  • 编码表

计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。
这就是编码表。

常见的编码表

 ASCII:美国标准信息交换码。
用一个字节的7位可以表示。
 ISO8859-1:拉丁码表。欧洲码表

GB2312:中国的中文编码表。最多两个字节编码所有字符

GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码

GBK等双字节编码方式,用最高位是1或0表示两个字节和一个字节 .如果为1 表示两个字节为1个字符,如果为0则一个字节为一个字符

Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的

字符码。所有的文字都用两个字节来表示

UTF-8:变长的编码方式,可用1-4个字节来表示一个字符

2 Unicode 的问题

Unicode不完美,这里就有三个问题,一个是,我们已经知道,英文字母只用一个字节表示就够了,第二个问题是如何才能区别Unicode和ASCII?计算机怎么知道两个字节表示一个符号,而不是分别表示两个符号呢?第三个,如果和GBK等双字节编码方式一样,用最高位是1或0表示两个字节和一个字节,就少了很多值无法用于表示字符,不够表示所有字符。

面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF- 8就是每次8个位传输数据,而UTF-16就是每次16个位。这是为传输而设计的编码在这里插入图片描述

中文在UTF-8编码方式中使用三个字节表示在这里插入图片描述

7 其他流的使用 了解

1 标准的输入,输出流

System.in 标准的输入流,默认从键盘输入

System.out 标准的输出流 ,默认从控制态输出

System类的setIn() /SetOut() 通过System类的setIn,setOut方法对默认设备进行改变

  • public static void setIn(InputStream in)
  • public static void setOut(PrintStream out)

例题*

从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续
进行输入操作,直至当输入“e”或者“exit”时,退出程序。

  public static void main(String[] args) {
        System.out.println("请输入信息(退出输入e或exit):");
// 把"标准"输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = null;
        try {
            while ((s = br.readLine()) != null) { // 读取用户输入的一行数据 --> 阻塞程序
                if ("e".equalsIgnoreCase(s) || "exit".equalsIgnoreCase(s)) {
                    System.out.println("安全退出!!");
                    break; }
// 将读取到的整行字符串转成大写输出
                System.out.println("-->:" + s.toUpperCase());
                System.out.println("继续输入信息");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close(); // 关闭过滤流时,会自动关闭它包装的底层节点流
                }
            } catch (IOException e) {
                e.printStackTrace();
            } }
    }

2 打印流

实现将基本数据类型的数据格式转化为字符串输出

打印流:PrintStreamPrintWriter

  • 提供了一系列重载的print()和println()方法,用于多种数据类型的输出

  • PrintStream和PrintWriter的输出不会抛出IOException异常

  • System.out返回的是PrintStream的实例

  • PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。

    在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类

  FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
        PrintStream printStream = new PrintStream(fileOutputStream);
        if (printStream != null){
            System.setOut(printStream);
        }
        byte[] buf  = new byte[10];
        int len=0;
        for (int i = 0; i <= 255; i++) { // 输出ASCII字符
            System.out.print((char) i);
            if (i % 50 == 0) { // 每50个数据一行
                System.out.println(); // 换行
            }
        }

3 数据流

数据流的作用是将基本类型的数据,或者字符串,读入或写出到磁盘中

数据流有两个类

 DataInputStream 和 DataOutputStream
 分别“套接”在 InputStream 和 OutputStream 子类的流上

DataInputStream中的方法

  • boolean readBoolean() byte readByte()
  • char readChar() float readFloat()
  • double readDouble() short readShort()
  • long readLong() int readInt()
  • String readUTF() void readFully(byte[] b)

DataOutpuStream 和DataInputStream 一样

数据流的使用

  @Test
    public void outtest() throws IOException {

        //将基本的数据类型写入文件中
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
        dos.writeInt(1);
        dos.writeUTF("你号");
        dos.writeBoolean(false);
        dos.close();

    }

    @Test
    public void intest() throws IOException {
        //将基本的数据类型从文件中读入
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        int i = dis.readInt();
        String s = dis.readUTF();
        boolean b = dis.readBoolean();
        System.out.println(i);
        System.out.println(s);
        System.out.println(b);


    }

8 对象流 * 重要

**1 对象的序列化机制 ***

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

2 序列化 与反序列化

序列化: 将内存中的对象,持久保存到持久化的文件中,如硬盘,数据库

反序列化,将硬盘的持久化的对象的二进制流文件转换为 内存中的对象

2 ObjectInputStream和OjbectOutputSteam

用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来

//1 实现序列化接口
public class Person implements Serializable {
    //2 添加序列化版本号
    public   static final long serialVersionUID = 4232342342L;

    private  int id;
    // static 和 transient 修饰的属性不可序列化
    private transient String name;
    //3 保证其内部属性可以序列化
    private Account account;
    private int age;

}


public class Account implements Serializable {

    public   static final long serialVersionUID = 423234234232L;
    private double balance;
}

2 创建对象流输出流序列化 Person 对象

  @Test
    public void  objectOutTest() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("datas.dat"));
        Person person = new Person();
        person.setId(1);
        person.setName("koam");
        person.setAge(10);
        Account account = new Account();
        account.setBalance(1000.0);
        person.setAccount(account);

        oos.writeObject(person);

        oos.flush();
        oos.close();

    }

2 创建对象输入流反序列化 Person 对象

 @Test
    public void  reverseSerilizable() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("datas.dat"));
        Object object = ois.readObject();
        Person person = (Person) object;
        System.out.println(person);
    }

结果
在这里插入图片描述
小结 重点

如果需要让某个对象支持序列化机制的要求

  1. 该类必须实现如下两个接口之一
  • Serializable
  • Externalizable

否则,会抛出NotSerializableException异常

  1. 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

private static final long serialVersionUID;

serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制

如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。

否则一旦序列化后,类发生了改变如属性的添加等,就不能反序列化对象了,因此修改后运行时环境自动修改了版本号,

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

  1. 保证对象的所有属性都是可以序列化的
  2. static 和 transient 修饰的属性不能被序列化

9 随机存储文件流

1 RandomAccessFile 类

  • 既可以当作输入流,也可以当作输出流

  • RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类。并且它实DataInput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。

  • RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件

    • 支持只访问文件的部分内容,可以向已存在的文件后追加内容
    • 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。
    • 如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖)
  • RnadomAccessFile 处理字节流,处理文本会有乱码问题
    RandomAccessFile 类对象可以自由移动记录指针:

  • long getFilePointer():获取文件记录指针的当前位置

  • void seek(long pos):将文件记录指针定位到 pos 位置

 @Test
    public void test() throws IOException {
        RandomAccessFile r = new RandomAccessFile("qq影音.jpg","r");
        RandomAccessFile rw = new RandomAccessFile("copy.jpg","rw");
        byte[] buf = new byte[10];
        int len=0;
        while ((len= r.read(buf)) !=-1){
           rw.write(buf,0,len);
        }

        r.close();
        rw.close();

    }
  • 创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式:

  • r: 以只读方式打开rw:打开以便读取和写入

  • rwd:打开以便读取和写入;同步文件内容的更新

  • rws:打开以便读取和写入;同步文件内容和元数据的更新

  • 如果模式为只读r。则不会创建文件,而是会去读取一个已经存在的文件,
    如果读取的文件不存在则会出现异常。 如果模式为rw读写。如果文件不
    存在则会去创建文件,如果存在则不会创建

RandomAccessFile实现数据插入操作

@Test
public void test3() throws IOException {

    RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

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

    //将StringBuilder中的数据写入到文件中
    raf1.write(builder.toString().getBytes());

    raf1.close();

    //思考:将StringBuilder替换为ByteArrayOutputStream
}

10 NIO 引入

1 NIO 概述

Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新 的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,

  • NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作
  • NIO将以更加高效的方式进行文件的读写操作

Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO

  • -java.nio.channels.Channel
    -----FileChannel:处理本地文件
    -----SocketChannel:TCP网络编程的客户端的Channel
    -----ServerSocketChannel:TCP网络编程的服务器端的Channel
    -----DatagramChannel:UDP网络编程中发送端和接收端的Channel

2 NIO2概述

随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。

3 Path、Paths和Files核心API

1 jdk 7.0 时,引入了 Path、Paths、Files三个类。
2.此三个类声明在:java.nio.file包下。
3.Path可以看做是java.io.File类的升级版本。也可以表示文件或文件目录,与平台无关
4.如何实例化Path:使用Paths.

  • static Path get(String first, String … more) : 用于将多个字符串串连成路径
  • static Path get(URI uri): 返回指定uri对应的Path路径

Path的常用方法

在这里插入图片描述

2 Files 用于操作文件或目录的工具类。

Files 常用方法
在这里插入图片描述

  • 复制,创建,删除,移动,文件大小

Files常用方法:用于判断
在这里插入图片描述

Files常用方法:用于操作内容
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值