IO框架

什么是流?

概念:内存与存储设备之间传输数据的通道,程序是运行在内存中 ,各类文件存储于硬盘中,流就是连接内存和存储设备的通道

流的分类

按方向

输入流:将【存储设备】中的内容读入到【内存】中

输出流:将【内存】中的内容写入到【存储设备】中

按单位:

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

字符流:以字符为单位,可以读写文本数据

按功能:

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

过滤流:在节点流的基础之上增强功能

字节流抽象类

字节输入流

字节输出流

FileInputStream的使用

public class Demo01 {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("d:\\aa.txt");

        //1、单个字节的读取
//        int len = 0;
//        while ((len=fis.read())!=-1){
//            System.out.println((char)len);
//        }

        //2、多个字节的读取(两种方法)
        byte[] buffer = new byte[3];
        //2-1第一种太蠢了,不建议看了
//        int count = fis.read(buffer);
//        System.out.println(new String(buffer));
//
//        int count2 = fis.read(buffer);
//        System.out.println(new String(buffer));
//
//        int count3 = fis.read(buffer);
//        System.out.println(new String(buffer,0,count3));

		//2-2记着这种写法即可
        int count = 0;
        while ((count=fis.read(buffer))!=-1){
            System.out.println(new String(buffer,0,count));
        }


        fis.close();
        System.out.println();
        System.out.println("搞定");
    }
}

 

FileOutputStream的使用

/**
 * FileOutStream字节的使用
 */
public class Demo02 {
    public static void main(String[] args) throws Exception{

        //1、创建文件字节输出流对象
        FileOutputStream fos = new FileOutputStream("d:\\aa.txt");

        //2、写入字节的两种方式
        //2-1、以字符的方式来写
        fos.write(97);
        fos.write('a');

        //2-1、直接使用
        //getBytes()使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。
        String name = "张三";
        fos.write(name.getBytes());

        //3、关闭流
        fos.close();
        System.out.println("finsh");

    }
}

 

字节输入流 BufferedInputStream

缓冲流:BufferedInputStream/BufferedOutputStream

优点:

提供了IO效率,减少访问磁盘的次数

一般来说数据都在硬盘中,有了缓冲流,数据就在缓冲区中,flush是将缓冲区的内容写入文件,也可以直接close

关闭缓冲流的同时,也会关闭输出或输入流

/**
 *BufferedInputStream 缓冲输入流
 *
 */
public class Demo04 {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("d:\\bb.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);

        int data=0;
        while ((data=bis.read())!=-1){
            System.out.print((char)data);
        }
        bis.close();
    }
}

 

字节输出流BufferedOutputStream

/**
 * 字节输出流文件用于写入数据
 */
public class Demo05 {
    public static void main(String[] args) throws Exception{
        //1、创建字节输出缓冲流
        FileOutputStream fis = new FileOutputStream("d:\\bb.txt");
        BufferedOutputStream bus = new BufferedOutputStream(fis);
        //2、写入文件
        String s = "man";
        for (int i = 0; i < 10; i++) {
            //写入的是一个8k的缓冲区
            bus.write(s.getBytes());
            //刷新到硬盘中
            bus.flush();
        }
        //3、关闭(内部自动调用flush方法)
        bus.close();
    }
}

 

对象流

对象流:ObjectInputStream\ObjectOutputStream

  1. 增强了缓冲区的功能

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

  3. 增强了读写对象的功能

    1. readObject()从流中读取一个对象

    2. writeObject(Object obj)向流中写入一个对象

使用流传输对象的过程叫做序列化,反序列化

序列化:把内存中的对象写入到流中

反序列化:从文件中读取的一个对象

序列化

/**
 *使用ObjectOutputStream实现对象的序列化
 * 提示:序列化的类必须使用Serializable接口,否则无法序列化
 */
public class Demo06 {
    public static void main(String[] args) throws Exception{
        //1、创建输出流
        FileOutputStream fis = new FileOutputStream("aa.txt");
        ObjectOutputStream obo = new ObjectOutputStream(fis);
        //2、实例化对象
        Student s = new Student("li",12);
        obo.writeObject(s);
        //3、关闭
        obo.close();

    }
}

Student类调用Serializable接口

public class Student implements Serializable {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 

反序列化

/**
 *ObjectInputStream实现反序列化(读取完成重构成对象)
 */
public class Demo07 {
    public static void main(String[] args) throws Exception{
        //1、创建对象流
        FileInputStream fis = new FileInputStream("aa.txt");
        ObjectInputStream obj = new ObjectInputStream(fis);
        //2、实现反序列化
        Student s1 = (Student) obj.readObject();
        //3、关闭流
        fis.close();
        System.out.println(s1.toString());
    }
}

 

 

序列化和反序列化的注意事项

1、序列化类必要实现Serializable接口

public class Student implements Serializable 

2、序列化类中对象属性要求实现Serializable接口

3、序列化的版本号serialVersionUID,可以保证序列化的类和反序列化的类是同一个类

private static final long serialVersionUID = 1L;

4、使用transient修饰后,就不能再序列化了

private transient String name;

5、静态属性不能被序列化

6、序列化多个对象,可借助集合实现

 

常见的字符编码

 

字符流抽象类

public class character01 {
    /**
     * 字符流抽象类
     * @param args
     */
    public static void main(String[] args) throws Exception{
        //1、创建FileinputStream对象
        FileInputStream fis = new FileInputStream("d:\\hello.txt");
        //2、读取
        int data = 0;
        while((data=fis.read())!=-1){
            System.out.print((char)data);
        }
        //3、关闭
        fis.close();
    }
}

字符输入流:Reader

字符输出流:Writer

当时用字节流FileInputStream进行读取汉字时,读取失败,因为字节流每次读取一个字节,而一个汉字时三个字节,所以无法读取成功。

 

FileReader的使用

/**
 * 使用FileReader读取文件
 */
public class Demo02 {
    public static void main(String[] args) throws Exception{
        //1、创建字符流
        FileReader fr = new FileReader("d:\\aa.txt");
        //2-1、第一种写法
//        int len=0;
//        while ((len=fr.read())!=-1){
//            System.out.println((char) len);
//        }
        //2-2、第二种使用数组
        char[] bytes = new char[1024];
        int len = 0;
        while ((len=fr.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
        //3、关闭流
        fr.close();
    }
}

 

FileWriter的使用

/**
 *使用FileWriter字符输出流写入文件
 */
public class Demo03 {
    public static void main(String[] args) throws Exception{
        FileWriter fw = new FileWriter("d:\\aa.txt");
        for (int i = 0; i < 3; i++) {
            fw.write("世界");
            fw.flush();
        }
        fw.close();
    }
}

 

字符流复制文件

思考为什么不能复制图片和二进制文件

答:字符流在输入或输出文件时,是以字符单位获取的,而图片和二进制文件都是0-1,会默认把0-1看做一个个字符,可以输出和输入,但是完成后无法打开,因为图片不是以字符的编码方式查看的

从硬盘读取获得的文件-》到内存中因为编码不同已经是乱码-》再复制出来还是乱码

/**
 /**
 *使用字符流复制文件
 * 思考为什么不能复制图片和二进制文件
 */
public class Demo04 {
    public static void main(String[] args) throws Exception{
        FileReader fileReader = new FileReader("d:\\aa.txt");
        FileWriter fileWriter = new FileWriter("d:\\cc.txt");

        ///如果aa的文件夹不为空,那么就把aa文件的内容写入到cc这个文件
        int len=0;
        while ((len=fileReader.read())!=-1){
            fileWriter.write(len);
            fileWriter.flush();
        }

        fileReader.close();
        fileWriter.close();
    }
}

 

字符缓冲流BufferedReader

用法简单

字符缓冲流的意义

/**
 *使用BufferedReader输入字符
 */
public class Demo05 {
    public static void main(String[] args) throws Exception{
        FileReader fileReader = new FileReader("d:\\aa.txt");
        BufferedReader bufferedReader = new BufferedReader(fileReader);

//        int len = 0;
//        while ((len=bufferedReader.read())!=-1){
//            System.out.println((char)len);
//        }

//        char[] chars = new char[1024];
//        int len=0;
//        while ((len=bufferedReader.read(chars))!=-1){
//            System.out.println(new String(chars,0,len));
//        }

        //新方法,可以直接读一行,不用再一个一个读
        String s = null;
        while ((s=bufferedReader.readLine())!=null){
            System.out.println(s);
        }

        bufferedReader.close();
    }
}

 

字符缓冲流BufferedWriter

/**
 *BufferedWriter字符缓冲流写入
 */
public class Demo06 {
    public static void main(String[] args) throws Exception{
        FileWriter fw = new FileWriter("d:\\ee.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        for (int i = 0; i < 4; i++) {
            bw.write("周淑怡爱整活");
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }
}

 

打印流

/**
 PrintWriter打印输出流
 */
public class Demo07 {
    public static void main(String[] args) throws Exception{
        PrintWriter pw = new PrintWriter("d://gg.txt");
        pw.println(123);
        pw.println(3.13);
        pw.println('a');
        pw.println("王菠萝");
        pw.close();
    }
}

 

转换流

桥转换流:InputStreamReader / OutputStreamWriter

桥转换流重点在于可以把输出、输入的文件,设置成自己所需要的编码方式,例如gbk,utf-8等等

 

转换流的使用

/**
 *转换桥接流InputStreamReader
 */
public class Demo08 {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("d:\\aa.txt");
        InputStreamReader isr = new InputStreamReader(fis,"gbk");
        int data;
        while ((data=isr.read())!=-1){
            System.out.print((char) data);
        }
        isr.close();
    }
}

 

/**
 *OutputStreamWriter输出转换流
 */
public class Demo09 {
    public static void main(String[] args) throws Exception{
        FileOutputStream fos = new FileOutputStream("d:\\ss.txt");
        OutputStreamWriter opsw = new OutputStreamWriter(fos,"gbk");
        for (int i = 0; i < 4; i++) {
            opsw.write("热爱生活!");
        }
        opsw.close();
    }
}

 

File类

概念:代表物理盘符中的一个文件或文件夹

常用的一些方法:(还有很多方法,可见JDK)

 

文件操作

/**
 * File类的使用
 * 1)分隔符
 * 2)文件操作
 * 3)文件夹操作
 */
public class Demo01 {
    public static void main(String[] args) throws Exception{
        fileope();
        separator();
    }
    //1)分隔符
    public static void separator(){
        System.out.println("路径分隔符:"+ File.pathSeparator);
        System.out.println("名称分隔符:"+ File.separator);
    }

    //2)文件操作
    public static void fileope() throws Exception{
        //1)创建文件
        //这里只是创建了文件对象 ,并没有创建这个文件
        File file = new File("d:\\test.txt");
//        System.out.println(file.toString());
        if (!file.exists()){
            boolean b = file.createNewFile();
            System.out.println("创建的结果:"+b);
        }
        //2)删除文件
        //2-1直接删除
//        System.out.println("删除的结果:"+file.delete());
        //2-2使用JVM退出时删除,延迟5秒删除
//        file.deleteOnExit();
//        Thread.sleep(5000);

        //3)获取文件信息
        //如果上方创建文件对象时没有指定盘符,则会默认创建在IDE中(项目文件夹下)
        System.out.println("获取文件的绝对路径:"+file.getAbsolutePath());
        System.out.println("获取路径:"+file.getPath());
        System.out.println("获取文件的名称:"+file.getName());
        System.out.println("获取父目录:"+file.getParent());
        System.out.println("获取文件长度:"+file.length());
        System.out.println("获取文件创建时间:"+new Date(file.lastModified()).toLocaleString());

        //4)判断
        System.out.println("是否可写:"+file.canWrite());
        System.out.println("是否是文件:"+file.isFile());
        System.out.println("是否隐藏:"+file.isHidden());
    }
}

 

文件夹操作

/**
 * File类的使用
 * 3)文件夹操作
 */
public class Demo02 {
    public static void main(String[] args) throws Exception{
        fileope();
    }
    //1)分隔符
    public static void separator(){

    }

    //2)文件操作
    public static void fileope() throws Exception{
        //1)创建文件
        File file = new File("d:\\aaa\\bbb\\vvv");
        System.out.println(file.toString());
        if (!file.exists()){
            //只能创建单节目录
//            file.mkdir();
            //创建多级目录
            file.mkdirs();
        }

        //2)删除文件
        //2-1直接删除
        //只能删除空目录
//        System.out.println(file.delete());
        //2-2使用JVM退出时删除,延迟5秒删除
//        file.deleteOnExit();
//        Thread.sleep(5000);

        //3)获取文件信息
        System.out.println("获取绝对路径:"+file.getAbsolutePath());
        System.out.println("获取路径:"+file.getPath());
        System.out.println("获取文件夹名称:"+file.getName());
        System.out.println("获取父目录:"+file.getParent());
        System.out.println("获取创建时间:"+new Date(file.lastModified()).toLocaleString());


        //4)判断
        System.out.println("是否是文件夹:"+file.isDirectory());
        System.out.println("是否隐藏:"+file.isHidden());

        //5)遍历文件夹
        File file2 = new File("C:\\Users\\oak\\Pictures\\Screenshots");
        String[] str = file2.list();
        System.out.println("--------------");
        for (String st:str) {
            System.out.println(st);
        }
    }
}

只用看54行以后就可以了

 

FileFilter接口

/**
 * File类的使用
 * 3)文件夹操作
 */
public class Demo02 {
    public static void main(String[] args) throws Exception{
        fileope();
    }
    //1)分隔符
    public static void separator(){

    }

    //2)文件操作
    public static void fileope() throws Exception{
        //1)创建文件
        File file = new File("d:\\aaa\\bbb\\vvv");
        System.out.println(file.toString());
        if (!file.exists()){
            //只能创建单节目录
//            file.mkdir();
            //创建多级目录
            file.mkdirs();
        }

        //2)删除文件
        //2-1直接删除
        //只能删除空目录
//        System.out.println(file.delete());
        //2-2使用JVM退出时删除,延迟5秒删除
//        file.deleteOnExit();
//        Thread.sleep(5000);

        //3)获取文件信息
        System.out.println("获取绝对路径:"+file.getAbsolutePath());
        System.out.println("获取路径:"+file.getPath());
        System.out.println("获取文件夹名称:"+file.getName());
        System.out.println("获取父目录:"+file.getParent());
        System.out.println("获取创建时间:"+new Date(file.lastModified()).toLocaleString());


        //4)判断
        System.out.println("是否是文件夹:"+file.isDirectory());
        System.out.println("是否隐藏:"+file.isHidden());

        //5)遍历文件夹
        File file2 = new File("D:\\");
        String[] str = file2.list();
        System.out.println("--------------");
        for (String st:str) {
            System.out.println(st);
        }

        //6)FileFilter接口的使用
        System.out.println("-------FileFilter接口的使用-------");
            File[] files3 = file2.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    if (pathname.getName().endsWith(".txt")) {
                        return true;
                    }
                    return false;
                }
            });
        for (File file1:files3) {
            System.out.println(file1.toString());
        }
    }
}

 

递归遍历和递归删除

/**
 * 案例一:递归遍历文件夹
 * 案例二:递归删除文件夹
 */
public class ListDemo {
    public static void main(String[] args) {
//        ListDir(new File("d:\\recursiontest"));
        deleteDir(new File("d:\\recursiontest"));
    }

    //递归遍历文件夹
    public static void ListDir(File dir){
        File[] files=dir.listFiles();
        System.out.println(dir.getAbsolutePath());
        if (files!=null&&files.length>0){
            for (File file:files){
                if (file.isDirectory()){
                    ListDir(file);
                }else{
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }
    //递归删除文件夹
    public static void deleteDir(File dir){
        File[] files=dir.listFiles();
        if (files!=null&&files.length>0){
            for (File file:files){
                if (file.isDirectory()){
                    deleteDir(file);
                }else {
                    System.out.println("删除文件"+file.getAbsolutePath()+file.delete());
                }
            }
        }
        System.out.println("删除文件夹目录"+dir.getAbsolutePath()+dir.delete());
    }
}

 

Properties

Properties的使用

/**
 *Properties的使用
 */
public class Demo03 {
    public static void main(String[] args) throws Exception{
        //1、创建集合
        Properties properties = new Properties();
        //2、添加数据
        properties.setProperty("username","zhangsan");
        properties.setProperty("age","20");
        System.out.println(properties.toString());

        //3-1、遍历keySet()
        Set set = properties.keySet();
        for (Object o:set) {
            System.out.println(o.toString()+"="+properties.get(o));
        }
        //3-2、entrySet
        //3-3、遍历stringPropertyNames()
        Set<String> pronames=properties.stringPropertyNames();
        for (String pro:pronames){
            System.out.println(pro+"="+properties.getProperty(pro));
        }

        //4、和流有关的方法
        //-------list方法
        PrintWriter pw = new PrintWriter("d:\\properties.txt");
        properties.list(pw);
        pw.close();

        //-------store方法另外保存文件
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\properties2.txt");
        properties.store(fileOutputStream,"注释zhushi");
        fileOutputStream.close();

        //-------load方法
        Properties properties2 = new Properties();
        FileInputStream fileInputStream = new FileInputStream("d:\\properties.txt");
        properties2.load(fileInputStream);
        fileInputStream.close();
        System.out.println(properties2.toString());
    }
}

  

 

posted @ 2022-02-15 09:58  里牧之  阅读(44)  评论(0)    收藏  举报