Java高级编程——IO流

目录

 

一、File类

二、IO流原理、分类

 三、字节流

四、字符流

五:随机访问流

六、内存流

七、字符编码格式


一、File类

1、概述

        1.1 定义:文件和文件目录路径的抽象表现形式

        1.2 可以对文件和目录进行新建、删除、重命名等操作,但访问文件本身内容要使用IO流

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

        1.4 实现了Serializable, Comparable两大接口,便于对象的序列化与比较

2、常用构造器与方法

2.1 参考API

3、路径分隔符(与系统有关)

        3.1 windows和DOS系统默认使用“\”来表示

        3.2 UNIX和URL使用“/”来表示

         3.3 Java中提供了public static final String separator这一变量根据操作系统,动态提供分隔符,来解决跨平台问题

 4、小练习

import org.junit.Test;

import java.io.File;
import java.io.FileFilter;

/**
 * @BelongsProject: day02_IO
 * @Author: XiaoBenBen
 * @Date: 2022/3/29 9:50
 * @Description: TODO
 *
 *      单元测试:@Test
 *
 */
public class Demo02 {

    @Test
    public void methon01(){
        /**
         *
         * @Author: XiaoBenBen
         * @Date: 2022/3/29
         * @Description:
         *          判断一个文件目录里面有几个文件和目录  --  不包含子目录
         *
         */
        File file = new File("G:\\360压缩\\360zip");

        int num1 = 0;//目录个数
        int num2 = 0;//文件个数
        File[] files = file.listFiles( );

//        for (int i=0;i<files.length;i++){
//            if (files.isFile() == true){
//                num1++;
//            }else {
//                num2++;
//            }
//        }
        for (File f:files){
            if (f.isFile() == true){
                num2++;
            }else {
                num1++;
            }
        }
        System.out.println("目录个数:" + num1 );
        System.out.println("文件个数:" + num2 );
    }


    @Test
    public void methon02(){
        /**
         *
         * @Author: XiaoBenBen
         * @Date: 2022/3/29
         * @Description:
         *
         *          创建方法输入目录,输出里面文件和目录的绝对路径 --  包含子目录
         *
         */

        File file = new File("G:\\千锋java\\GZ-2202(1)\\2022-codes\\week03");
        methon03(file);
    }

    public void methon03(File file){
        File[] files = file.listFiles( );

        for (File f:files){
            if (f.isDirectory() == true){
                //要传递f
                methon03(f);
            }
            System.out.println(f.getAbsolutePath());
        }
    }

    @Test
    public void methon04(){
//        File file = new File("E:\\File\\File1");
//        //删除失败,只能删除空目录
//        file.delete();

        //删除成功
        File file = new File("E:\\File\\File3");
        file.delete();
    }

    @Test
    public void methon05(){
        File file = new File("E:\\File\\File4\\File4.1");

        //只创建当前目录
//        file.mkdir();

        //会把不存在的父目录创建
        file.mkdirs();
    }

    //输出指定目录所有的java结尾的文件的绝对路径
    @Test
    public void methon06(){
        File file = new File("E:\\File");
        methon07(file);
    }
    public void methon07(File file){
        File[] files = file.listFiles( );
        for (File f:files){
//            if (f.getName().endsWith("java")){
//                System.out.println(f.getAbsolutePath() );
//            }
            //有可能是目录
            if (f.isDirectory()){
                methon07(f);
            }else if (f.getName().endsWith("java")){
                System.out.println(f.getAbsolutePath() );
            }
        }
    }
    //listFiles(FileFilter filter)
    //返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
    @Test
    public void methon08(){
        File file = new File("E:\\File");
        methon09(file);
    }

    public void methon09(File file){
        File[] files = file.listFiles(new FileFilter( ) {
            @Override
            public boolean accept(File pathname) {
                //System.out.println("pathname:"+pathname);
                //判断是否为目录
                if(pathname.isDirectory()){
                    return true;
                }else if(pathname.isHidden()){
                    System.out.println("隐藏文件:"+pathname.getAbsolutePath());
                }
                return false;
            }
        });
        for (File f:files){
            methon09(f);
        }
    }

}

二、IO流原理、分类

1、IO流概述

        1.1 I/O是Input/Output缩写,I/O技术是非常实用的技术,用于
处理设备之间的数据传输。

        1.2 Java中,对于数据的输入/输出操作以“流(Stream)”的方式进行,java.io包下提供了各种“流”类和接口。

2、I/O流概念及原理

        2.1 概念:内存与存储设备之间传输数据的通道。

        2.2 原理(站在程序的角度):

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

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

3、流的分类

        3.1 按方向:输入流与输出流

        3.2 按数据单位:

                3.2.1 字节流:以字节为单位,可以读写所有数据

                3.2.2 字符流:以字符为单位。只能读写文本数据

        3.3 按功能:

                3.3.1 节点流:具有实际传输数据的读写功能

                3.3.2 过滤流(处理流):在节点流的基础上增强功能

4、IO体系

 三、字节流

1、字节节点流:InputStream与Reader

        1.1 常用方法见API

        1.2 典型实现:FileInputStream与FileOutputStream

案例:字节输入流:FileInputStream

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @BelongsProject: day02_IO
 * @Author: XiaoBenBen
 * @Date: 2022/3/29 14:25
 * @Description: TODO
 *
 *          IO流:
 *  *          1.按照数据传输的方向进行划分:以程序作为参照物
 *  *               输入流    文件 -> 程序    读取
 *  *               输出流    程序 -> 文件    写出
 *  *          2.按照读写数据的单位进行划分
 *  *              字节流     byte
 *  *              字符流     char
 *  *          3.根据功能进行划分
 *  *              基础流
 *  *              包装流
 *
 *
 *
 */
public class Demo01 {
    /**
     *
     * @Author: XiaoBenBen
     * @Date: 2022/3/29
     * @Description:  //每次读取一个字节读取完整个文件的内容
     */

    @Test
    public void methon01()  {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("IO01.txt");
            int read;
            while ((read = fis.read()) != -1){
                System.out.print((char)read );
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace( );
        } catch (IOException e) {
            e.printStackTrace( );
        }
        finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace( );
                }
            }
        }
    }
    
    @Test
    public void methon02(){
        /**
         *
         * @Author: XiaoBenBen
         * @Date: 2022/3/29
         * @Description:  //使用字节输入流每次读取一个缓冲区的数据,读取完整个文件
         */
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("IO01.txt");

            //一次读取1024个字节
            byte[] b = new byte[1024];
            int len ;
            while ((len = fis.read(b)) != -1){
                System.out.println(new String(b,0,len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace( );
        } catch (IOException e) {
            e.printStackTrace( );
        }
        finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace( );
                }
            }
        }
    }

}

案例:字节输出流:FileOutputStream

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @BelongsProject: day02_IO
 * @Author: XiaoBenBen
 * @Date: 2022/3/29 19:37
 * @Description: TODO
 *
 *          文件字节输出流
 *
 *          ps:用完关闭
 *
 */
public class Demo02 {

    @Test
    public void methon01(){
        try {
            FileOutputStream fid = new FileOutputStream("IO01.txt");
            fid.write(97);
        } catch (FileNotFoundException e) {
            e.printStackTrace( );
        } catch (IOException e) {
            e.printStackTrace( );
        }
    }

    //每次写入时,内容清空后写入
    @Test
    public void methon02() throws IOException {
        FileOutputStream fid = new FileOutputStream("IO01.txt");
        String str = "没救了";
        fid.write(str.getBytes());
        fid.close();
    }

    //在末尾写入
    @Test
    public void methon03() throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("IO01.txt",true);
        fileOutputStream.write(98);
        fileOutputStream.close();

    }


}

案例:字拷贝流

import org.junit.Test;
import java.io.*;
/**
 * @BelongsProject: day02_IO
 * @Author: XiaoBenBen
 * @Date: 2022/3/29 20:08
 * @Description: TODO
 *
 *              字节拷贝流
 */
public class Demo03 {
    @Test
    public void methon01() throws IOException {
        //字节输入
        FileInputStream fid = new FileInputStream("IO01.txt");
        //字节输出
        FileOutputStream fis = new FileOutputStream("IO01copy.txt");
        byte[] bytes = new byte[1024];
        int len;

        while ((len = fid.read(bytes)) != -1){
            fis.write(bytes,0,len);
        }
        fid.close();
        fis.close();
    }
}

2、字节缓冲流:BufferedInputStream和BufferedOutputStream

        2.1 提高IO效率,减少访问磁盘的次数

        2.2 数据存储在缓冲区,flush或者close将缓冲区的内容写入文件

 案例:

import org.junit.Test;
import javax.print.attribute.standard.Fidelity;
import java.io.*;

/**
 * @BelongsProject: day03_IO2
 * @Author: XiaoBenBen
 * @Date: 2022/3/30 10:10
 * @Description: TODO
 *
 *      按功能划分:
 *          基础流(节点流):直接与磁盘交互
 *          包装流(处理流):基于节点流基础上,通过缓冲区进行读写
 *              - 提高IO效率,减少访问磁盘的次数。
 *              - 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
 *
 */
public class Demo01 {

    //字节缓冲输入流
    @Test
    public void methon01() throws IOException {
        FileInputStream fis = new FileInputStream("IO02.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
//        byte[] bytes = new byte[1024];
        int read = bis.read( );
        System.out.println((char)read);

        bis.close();
    }

    //字节缓冲输出流
    @Test
    public void methon02() throws IOException {
        FileOutputStream fos = new FileOutputStream("IO04.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //写入单个
        bos.write(97);

        bos.close();
    }
}

3、对象流:ObjectOutputStream与ObjectInputStream(序列化与反序列化)

        3.1 增强了缓冲区功能

        3.2 增强了读写8种基本数据类型和字符串功能

        3.3 增强了读写对象的功能readObject() 从流中读取一个对象,writeObject(Object obj) 向流中写入一个对象。

        3.4 自定义类必须实现Serializable接口,实现该接口后,有一个表示序列化版本标识符的静态变量: private static final long serialVersionUID;若没显示,则它的值为Java运行时环境根据类的内部细节自 动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。

        3.5 不能序列化static和transient修饰的成员变量

案例:

import org.junit.Test;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 *
 *             对象流:针对对象的读写操作
 *                  ObjectInputStream:对象输入流
 *                 ObjectOutputStream:对象输出流
 *
 *            使用对象流进行读写操作对象类需要实现 Serializable 接口
 *            使用对象流进行读写操作本质上是在进行序列化和反序列化
 *            写入对象序列化(加密)
 *            读取对象反序列化(解密)
 *
 *            反序列化的序列号跟序列化时的序列号一致
 *            类结构发生改变序列号也会跟着改变
 *              类结构要么一致或者手动添加序列化时的序列号
 */
public class Demo01 {
    //创建对象并使用字符流写入到文件中
    @Test
    public void method01() throws IOException {
        User user = new User(1, "zs");
        BufferedWriter bw = new BufferedWriter(new FileWriter("IO9.txt"));
        String str = user.toString();
        System.out.println(str);
        bw.write(str);
        bw.close();
    }

    //创建对象并使用对象流写入文件中   --  对象类需要实现 Serializable 接口
    @Test
    public void method02() throws IOException {
        User user = new User(1, "zs");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO9.txt"));
        oos.writeObject(user);
        oos.close();
    }

    //创建多个对象并使用对象流写入文件中   --  对象类需要实现 Serializable 接口
//    @Test
//    public void method03() throws IOException {
//        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO9.txt"));
//        oos.writeObject(new User(1, "zs"));
//        oos.writeObject(new User(2, "ls"));
//        oos.writeObject(new User(3, "ww"));
//        oos.writeObject(new User(4, "z6"));
//        oos.close();
//    }

    //创建多个对象并使用对象流写入文件中,最后加入一个null对象   --  对象类需要实现 Serializable 接口
    //中途加入null对象会在读取的时候数据丢失
    @Test
    public void method04() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO9.txt"));
        oos.writeObject(new User(1, "zs"));
        oos.writeObject(new User(2, "ls"));
        oos.writeObject(null);
        oos.writeObject(new User(3, "ww"));
        oos.writeObject(new User(4, "z6"));
        oos.writeObject(null);
        oos.close();
    }

    //创建多个对象存放到集合中,并使用对象流写入文件   --  对象类需要实现 Serializable 接口
    @Test
    public void method05() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO9.txt"));
        ArrayList<User> list = new ArrayList<>();
        //通过工具类把多个对象存储到集合中
        Collections.addAll(list,
                new User(1, "zs"),
                new User(2, "ls"),
                null,
                new User(3, "ww"),
                new User(4, "z6"));
        //使用对象流写入一个集合对象
        oos.writeObject(list);
        oos.close();
    }
}
import org.junit.Test;
import java.io.*;
import java.util.ArrayList;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 */
public class Demo02 {
    //使用字符流读取文件中的数据
    @Test
    public void method01() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("IO9.txt"));
        String str = br.readLine();
        //获取文件中的属性封装成对象很麻烦
    }

    //使用对象流读取文件中的一个对象
    @Test
    public void method02() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO9.txt"));
        User user = (User)ois.readObject();
        System.out.println(user.getId()+":"+user.getName());
        ois.close();
    }

    //使用对象流读取文件中的多个对象   --  读少会数据丢失,读多会报错
    @Test
    public void method03() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO9.txt"));
        User user1 = (User)ois.readObject();
        User user2 = (User)ois.readObject();
        User user3 = (User)ois.readObject();
        //User user4 = (User)ois.readObject();
        //User user5 = (User)ois.readObject();
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user3);
        //System.out.println(user4);
        //System.out.println(user5);
        ois.close();
    }

    //使用对象流读取文件中的多个对象,最后一个对象是null对象
    @Test
    public void method04() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO9.txt"));
        User user;
        while((user = (User)ois.readObject()) != null ){
            System.out.println(user);
        }
        ois.close();
    }

    //使用对象流读取文件中的一个集合对象
    @Test
    public void method05() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO9.txt"));
        ArrayList<User> list = (ArrayList<User>)ois.readObject();
        list.forEach(item -> System.out.println(item));
        ois.close();
    }
}

User类和工具类

import java.io.Serializable;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 */
public class User implements Serializable {
    //序列号   --  会随着类的结构发生改变
    //只有 id 和 name 属性的序列号
    //public static final long serialVersionUID = 8166679888839442012L;
    // id ,name,age 3个属性的序列号
    //public static final long serialVersionUID = 6479593650878686132L;
    private int id;
    private String name;
    //private int age;

    //私有的静态常量不会被序列化           --  不会影响序列号
    //private static final int AGE = 1;

    //私有的 transient 属性不会被序列化    --  不会影响序列号
    private transient int age;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
import java.io.Closeable;
import java.io.IOException;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 */
public class IOUtils {
    /**
     * 关闭多个流的方法
     *  Closeable 为 IO流的共同实现的接口
     * @param closeables
     */
    public static void closeAll(Closeable ... closeables){
        //循环第一次 closeable 为 fis
        //循环第二次 closeable 为 isr
        //循环第二次 closeable 为 br
        for (Closeable closeable:closeables) {
            if(closeable != null){
                try {
                    closeable.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

四、字符流

1、抽象类Reader与Writer

        1.1 常用方法见API

        2.2 典型实现:字符节点流FileReader 与FileWriter   

案例:字符输出流:FileReader

案例:字符输出流:FileWriter     不可拷贝图片和视频

import org.junit.Test;
import java.io.*;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 *
 *      字符流:针对文本文件的流,读写单位为字符
 *          文件字符输入流:FileReader
 *          文件字符输出流:FileWriter
 */
public class Demo02 {

    //读取单个字符
    @Test
    public void method01() throws IOException {
        FileReader fr = new FileReader("IO1.txt");
        int read = fr.read();
        System.out.println((char)read);
    }

    //读取单个字符读完整个文件
    @Test
    public void method02() throws IOException {
        FileReader fr = new FileReader("IO1.txt");
        int read;
        while((read = fr.read()) != -1){
            System.out.print((char)read);
        }
        fr.close();
    }

    //使用缓冲区读取完整个文件
    @Test
    public void method03() throws IOException {
        FileReader fr = new FileReader("IO1.txt");
        //读取数据为字符,所以数组类型为字符数组
        char[] c = new char[3];
        int len;
        while((len = fr.read(c)) != -1){
            System.out.print(new String(c,0,len));
        }
        fr.close();
    }

    //使用字符输出流写出数据到文件中
    @Test
    public void method04() throws IOException {
        FileWriter fw = new FileWriter("IO2.txt");
        fw.write("术尚可求");
        fw.close();
    }

    //末尾追加
    @Test
    public void method05() throws IOException {
        FileWriter fw = new FileWriter("IO2.txt", true);
        fw.write(",有术无道,止于术");
        fw.close();
    }

    //拷贝    --  文本文件
    @Test
    public void method06() throws IOException {
        FileReader fr = new FileReader("IO2.txt");
        FileWriter fw = new FileWriter("IO3.txt");
        char c[] = new char[1024];
        int len;
        while((len = fr.read(c)) != -1){
            fw.write(c,0,len);
        }
        fr.close();
        fw.close();
    }

    //拷贝    --  视频(不可拷贝)
    @Test
    public void method07() throws IOException {
        FileReader fr = new FileReader("video01.mp4");
        FileWriter fw = new FileWriter("video02.mp4");
        char c[] = new char[1024];
        int len;
        while((len = fr.read(c)) != -1){
            fw.write(c,0,len);
        }
        fr.close();
        fw.close();
    }

    //拷贝    --  图片(不可拷贝)
    @Test
    public void method08() throws IOException {
        FileReader fr = new FileReader("dqwj.jpg");
        FileWriter fw = new FileWriter("dqwj02.jpg");
        char c[] = new char[1024];
        int len;
        while((len = fr.read(c)) != -1){
            fw.write(c,0,len);
        }
        fr.close();
        fw.close();
    }
}

2、字符缓冲流:BufferedReader和BufferedWriter

        2.1 支持输入换行符,可以一次读写一行操作。

案例:

import org.junit.Test;
import java.io.*;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 *
 *          带缓冲区的字符流:
 *              BufferedReader
 *              BufferedWriter
 *
 *              readLine() 是读取一行,不包含换行符,是 BufferedReader 独有的方法
 *              newLine()  是换行,也是 BufferedWriter 独有的方法
 */
public class Demo02 {
    //拷贝
    @Test
    public void method01() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("IO6.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("IO7.txt"));
        char[] c = new char[1024];
        int len;
        while((len = br.read(c)) != -1){
            bw.write(c,0,len);
        }
        br.close();
        bw.close();
    }

    @Test
    public void method02() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("IO6.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("IO7.txt"));
        String str;
        //readLine() 读取一行数据,但是不包括换行符
        while((str = br.readLine()) != null){
            bw.write(str);
            //换行
            bw.newLine();
        }
        br.close();
        bw.close();
    }
}

3、打印流:PrintStream和PrintWriter(了解)

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

        3.1 封装了print()和println()方法,支持写入后换行,支持打印数据原样

案例:

import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 *          打印流:只有输出,没有输入
 *              PrintStream:打印字节流
 *              PrintWriter:打印字符流
 *
 */
public class Demo01 {
    @Test
    public void method01(){
        //打印到控制台
        System.out.println("123");
    }

    @Test
    public void method02() throws FileNotFoundException {
        PrintStream ps = new PrintStream("IO3.txt");
        //写出字节
        //ps.write(97);
        //打印数据
        ps.println(97);
        ps.close();
    }

    //输出重定向
    @Test
    public void method03() throws FileNotFoundException {
        //System.out    获取标准输出流 --  目的源固定为控制台
        System.out.println("有道无术");
        //改变目的源
        System.setOut(new PrintStream("IO4.txt"));
        System.out.println("术尚可求");
    }

    public static void main(String[] args) throws FileNotFoundException {
        //改变来源
        System.setIn(new FileInputStream("IO3.txt"));
        //System.in     获取标准输入流 --  来源固定为控制台
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数字");
        int num = sc.nextInt();
        System.out.println("num:"+num);
    }
}

4、转换流:InputStreamReader和OutputStreamWriter

        4.1 提供了在字节流和字符流之间的转化

        4.2 InputStreamReader:将InputStream转化为Reader

              OutputStreamWriter:将Writer转换为OutputStream

        4.3 可以指定字符编码方式

案例:

public class TestInputStreamReader {
	public static void main(String[] args) throws Exception {
		//1创建InputStreamReader对象
		FileInputStream fis=new FileInputStream("d:\\write.txt");
		InputStreamReader isr=new InputStreamReader(fis, "gbk");
		//2读取文件
		int data=0;
		while((data=isr.read())!=-1) {
			System.out.print((char)data);
		}
		//3关闭
		isr.close();
	}
}
public class TestOutputStreamWriter {
	public static void main(String[] args) throws Exception{
		//1创建OutputStreamWriter
		FileOutputStream fos=new FileOutputStream("d:\\info.txt");
		OutputStreamWriter osw=new OutputStreamWriter(fos, "utf-8");
		//2写入
		for(int i=0;i<10;i++) {
			osw.write("我爱北京,我爱故乡\r\n");
			osw.flush();
		}
		//3关闭
		osw.close();
		System.out.println("执行成功");
	}
}

五:随机访问流

1、随机访问流:RandomAccessFile

import org.junit.Test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 *          RandomAccessFile:随机访问流      --  字节流
 *              1.一个类可以创建输入流对象和输出流对象
 *              2.拥有指针(偏移量)
 *              3.创建对象不会清空文件的数据
 *              4.创建新对象,偏移量都从0开始
 */
public class Demo01 {
    //使用随机访问流从文件中间开始读取数据
    @Test
    public void method01() throws IOException {
        //创建随机访问流对象 --  模式为读取模式
        RandomAccessFile ranR = new RandomAccessFile("IO1.txt","r");
        //获取偏移量
        long pointer = ranR.getFilePointer();
        System.out.println("读取前的偏移量:"+pointer);
        //设置偏移量
        ranR.seek(15);
        //获取偏移量
        pointer = ranR.getFilePointer();
        System.out.println("设置完偏移量后:"+pointer);

        byte[] b = new byte[1024];
        int len;
        while((len = ranR.read(b)) != -1){
            System.out.println(new String(b,0,len));
        }

        //读取结束后获取偏移量
        pointer = ranR.getFilePointer();
        System.out.println("文件读取结束的偏移量:"+pointer);
        ranR.close();
    }

    //使用随机访问流写入数据   --  会覆盖原数据
    @Test
    public void method02()throws IOException {
        //没有清空原有的数据
        RandomAccessFile ranR = new RandomAccessFile("IO1.txt","rw");
        //有道无术,术尚可求,
        //a��道无术,术尚可求,
        //在指定偏移量开始覆盖写入
        ranR.write(97);
        ranR.close();
    }

    //使用随机访问流写入数据   --  末尾追加
    @Test
    public void method03()throws IOException {
        RandomAccessFile ranR = new RandomAccessFile("IO1.txt","rw");
        //获取文件的长度
        long length = ranR.length();
        //设置偏移量
        ranR.seek(length);
        ranR.write(97);
        ranR.close();
    }

    //使用随机访问流写入不同数据类型的数据    --  写入 long 类型的数据
    @Test
    public void method04()throws IOException {
        RandomAccessFile ranR = new RandomAccessFile("IO2.txt","rw");
        //写入 long 类型数据
        ranR.writeLong(10);
        ranR.close();
    }

    //使用随机访问流读取long类型的数据
    @Test
    public void method05()throws IOException {
        RandomAccessFile ranR = new RandomAccessFile("IO2.txt","r");
        long num = ranR.readLong();
        System.out.println("long:"+num);
        ranR.close();
    }

    //断点续传
    @Test
    public void method06() throws IOException {
        //1.创建对象
        RandomAccessFile ranR = new RandomAccessFile("QQ1.mp4", "r");
        RandomAccessFile ranW = new RandomAccessFile("QQ2.mp4", "rw");
        //2.获取目标文件的长度
        long length = ranW.length();
        //3.设置源文件对象和目标文件对象的偏移量
        ranR.seek(length);
        ranW.seek(length);
        //4.读写操作
        byte[] b = new byte[2];
        int len;
        while((len = ranR.read(b)) != -1){
            ranW.write(b,0,len);
        }
        ranR.close();
        ranW.close();
    }
}

六、内存流

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @author XiaoBenBen
 * @since JDK 1.8
 *
 *          内存流:无法关闭,运行效率非常高,存放的数据量少
 *              ByteArrayOutputStream:程序输出到内存中
 *              ByteArrayInputStream:内存读取到程序中
 *
 */
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //内存输出流 --  固定输出到内存里
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bos.write("有道无术".getBytes());
        bos.close();

        //内存输入流 --  从内存读取数据
        //获取存放数据的数组
        byte[] bytes = bos.toByteArray();
        System.out.println("----直接转字符串-----");
        System.out.println(new String(bytes));
        System.out.println("----通过toString获取数据---");
        //把流里的数据转换字符串
        System.out.println(bos.toString());

        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        byte[] b = new byte[1024];
        int len;
        System.out.println("----通过输入流获取数据----");
        while((len = bis.read(b)) != -1){
            System.out.println(new String(b,0,len));
        }
        //清空流里的数据
        bis.reset();
        bis.close();
    }
}

七、字符编码格式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值