IO流基础笔记

什么是流?

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

流的分类

按方向:

  • 输入流,将<存储设备>中的内存读入到<内存>中。
  • 输出流,将<内存>中的内容写入到<存储设备>中。

按单位:

  • 字节流:以字节为单位,可以读写所有数据。
  • 字符流:以字符为单位,只能读写文本数据。

按功能:

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础上增强功能
字节流

字节流的父类(抽象类) 不可实例化

  • InputStream: 字节输入流(读)

    • FileInputStream:public int read(byte[] b) //从流中读取多个字节,将读到的内容传递给b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1;
  • OutputStream:字节输出流(写)

    • FileOutputStream:public void write (byte[] b) //一次写多个字节,将b数组中所有字节写入输入流

使用FileInputSream读取数据

//1.创建FileInputStream,并指定文件路径
        FileInputStream fis = new FileInputStream("D:\\国家机密\\IO流\\aaa.txt");
        //2.读取文件
        //fis.read();
        //2.1单个字节获取
//        int data = 0;
//        while((data = fis.read()) != -1){
//            System.out.print((char) data);
//        }
        //2.2多个字节获取
        byte[] buf = new byte[10];
        int count = 0;
        while ((count = fis.read(buf)) != -1){
            //创建字符串对象 String str = new String("");
            System.out.println(new String(buf,0,count));
        }

        //3.关闭
        fis.close();
        System.out.println("执行完毕");

//结果是
abcdefg
执行完毕

使用FileOutputSream写入数据

//1.创建文件字节输出流
FileOutputStream fos = new FileOutputStream("D:\\国家机密\\IO流\\bbb.txt");
//2.写入文件
fos.write(97);
fos.write(98);
fos.write(99);
//3.关闭
fos.close();
System.out.println("执行完毕");

//写入多个数据
String string = "HelloWorld";
//getbyte方法  获取字符串所对应的字节数
fos.write(string.getBytes());

//如果想要输入的信息是追加而不是覆盖 可在创建对象时添加true参数
FileOutputStream fos = new FileOutputStream("D:\\国家机密\\IO流\\bbb.txt",true);

复制文件

//1.创建流
//1.1文件字节输入流
FileInputStream fis = new FileInputStream("D:\\国家机密\\IO流\\1.jpg");
//1.2文件字节输出流
FileOutputStream fos = new FileOutputStream("D:\\国家机密\\IO流\\2.jpg");

int count = 0;
byte[] buf = new byte[1024];

while((count = fis.read(buf)) != -1){
    fos.write(buf,0,count);
}
//3.关闭
fis.close();
fos.close();
System.out.println("复制完毕");
字节缓冲流 BufferedInputStream/BufferedOutputStream
  • 提高IO效率,减少访问磁盘的次数
  • 数据存储在缓冲区中,flush是将缓存区的内容写入文件中

使用BufferedInputSream读取数据

//1创建BufferedInputStream
        FileInputStream fis = new FileInputStream("D:\\国家机密\\IO流\\aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        //2读取
//        int data = 0;
//        while ((data = bis.read()) != -1){
//            System.out.println((char)data);
//        }

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

        //3关闭
        bis.close();
        System.out.println("执行完毕");

使用BufferedInputSream写入数据

FileOutputStream fos = new FileOutputStream("D:\\国家机密\\IO流\\buffer.txt");

        //1.创建字节输出缓冲流
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //2.写入文件
        for (int i = 0;i<10;i++){
            bos.write("HelloWorld".getBytes());
            bos.flush();//刷新到硬盘  执行一半断电了数据还在
        }
        //3. 关闭(内部调用flush方法)
//        bos.close();
//        System.out.println("执行成功");
对象流

ObjectOutputStream/ObjectInputStream

  • 增强了缓冲区的功能
  • 增强了读写8种基本数据类型和字符串功能
  • 增强了读写对象共功能
    • readObject() 从流中读取一个对象
    • writeObject(Object obj) 向流中写一个对象

使用流传输对象的过程称为序列化(写入文件)、反序列化(读取文件)。

序列化

//1.创建一个对象流
FileOutputStream fos = new FileOutputStream("D:\\国家机密\\IO流\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);

//2.序列化(写入操作)
Student zhangsan = new Student("张三",20);
oos.writeObject(zhangsan);

//3.关闭
oos.close();
System.out.println("执行完毕");

//前提条件  对象必须实例化Seriallizable标记接口
public class Student implements Serializable 
反序列化
//1.创建对象流
   FileInputStream fis = new FileInputStream("D:\\国家机密\\IO流\\stu.bin");
   ObjectInputStream ois = new ObjectInputStream(fis);

   //2.读取文件(反序列化)
   Object obj = ois.readObject();
//  Object obj2 = ois.readObject();  只能读取一次否则报错
//  Exception in thread "main" java.io.EOFException


   //3.关闭
   ois.close();
   System.out.println("执行完毕");
   System.out.println(obj.toString());
序列化与反序列化的注意事项
  1. 序列化类必须要实现Serializeable接口

    public class Student implements Serializable 
    
  2. 序列化类中对象属性要求实现 Serializeable接口

    (类中如果再实例化一个类,那么这个类也必须实现接口)

  3. 序列化版本号ID,保证序列化的类和反序列化的类是同一个类

    private static final long serialVersionUID = 100;//数值可随意填写
    
    //  ID不同  反序列化会报错
    //  Exception in thread "main" java.io.InvalidClassException
    
    //解决办法 1. 更改ID保持一致  2. 重新序列化
    
  4. 使用transient(意思:瞬间的)修饰属性,该属性就不会被序列化

    private transient int age;
    
  5. 静态属性不可序列化

  6. 序列化多个对象

    // 写入两个对象
    Student zhangsan = new Student("张三",20);
    Student lisi = new Student("李四",21);
    
    //读取两次(麻烦)
    Object obj1 = ois.readObject();
    Object obj2 = ois.readObject();
    
    //第二种方法
    //使用集合写入
    ArrayList<Object> list = new ArrayList<>();
            list.add(zhangsan);
            list.add(lisi);
            oos.writeObject(list);
    //读取一次(方便)
    Object obj1 = ois.readObject();
    //或者
    ArrayList<Object> list = (ArrayList<Object>) ois.readObject();
    
字符编码
  • ISO-8859-1 收录除ASCII外,还包西欧,希腊语,泰语、阿拉伯语、希伯来语对应的文字符号
  • UTF-8 针对Unicode码表的可变长度字符编码(1,2,3个字节表示字符,对于中文一个汉字三个字节)
  • GB2312 简体中文(1,2个字节表示字符)
  • GBK 简体中文、对于GB2312的扩充(1,2个字符表示)可编译ANSI文件
  • BIG5 台湾 繁体中文

当编码方式和解码方式不一致时,会出现乱码

字符流

字符流父类

  • Reader

    • FileReader

      public int read(char[] c)  //从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部。则返回-1
      
  • Writer

    • FileWriter

      public void write(String str)  //一次写多个字符,将b数组中所有字符,写入输出流
      

使用FileReader读取文档

//1.创建FileReader  文件字符输入流
        FileReader fr = new FileReader("D:\\国家机密\\IO流\\hello.txt");

        //2.读取
        //2.1单个字符读取
//        int data = 0;
//        while ((data = fr.read()) != -1){//读取一个字符
//            System.out.print((char) data);
//        }

        //缓冲区
        char[] buf = new char[2];
        int count = 0;
        while((count = fr.read(buf)) != -1){
            System.out.println(new String(buf,0,count));
        }

        //3关闭
        fr.close();

使用FileWriter写入数据

//1.创建FileWriter对象
FileWriter fw = new FileWriter("D:\\国家机密\\IO流\\write.txt");

//2.写入
for (int i = 0;i<10;i++){
    fw.write("java是世界上最好的语言\n");
    fw.flush();
}

//3.关闭
fw.close();
System.out.println("执行完毕");

复制文件

//只能复制文本文件,不能复制图片或二进制文件(视频,音乐等都是以二进制存储的)因为没有字符编码

//1.创建FileReader
FileReader fr = new FileReader("D:\\国家机密\\IO流\\write.txt");

//2.创建FileWriter
FileWriter fw = new FileWriter("D:\\国家机密\\IO流\\write2.txt");

int data = 0;
while ((data = fr.read()) != -1){
    fw.write(data);
    fw.flush();
}


//3.关闭
fr.close();
fw.close();
System.out.println("执行完毕");
字符缓冲流 BufferedReader/BufferedWriter
  • 高效读写
  • 支持输入换行符
  • 可一次写一行,读一行

BufferedReader读取文件

//1.创建字符缓冲流  BufferedReader
        FileReader fr = new FileReader("D:\\国家机密\\IO流\\write.txt");
        BufferedReader br = new BufferedReader(fr);

//        //2.读取 第一种方式
//        char[] buf = new char[1024];
//        int count = 0;
//        while ((count = br.read(buf)) != -1){
//            System.out.println(new String(buf,0,count));
//        }

        //2.1按行读取   第二种方式   readLine() 获得一行的字符
        String line = null;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }


        //3.关闭
        br.close();
        System.out.println("执行完毕");

BufferedWrite写入文件

//1.创建BufferedWriter
        FileWriter fw = new FileWriter("D:\\国家机密\\IO流\\buffer.txt");
        BufferedWriter bw = new BufferedWriter(fw);

//        //2.写入
        for (int i = 0; i < 10 ; i++){
            bw.write("好好学习天天向上");
            bw.newLine(); // 换行符
            bw.flush();
        }


        //3.关闭
        bw.close();
        System.out.println("执行完毕");
打印流 PrintWriter
  • 封装了print()/println()方法,支持写入后换行
  • 支持数据原样打印
//1. 创建打印流
PrintWriter pw = new PrintWriter("D:\\国家机密\\IO流\\print.txt");

//2.打印
pw.println(97);
pw.println(true);
pw.println(3.14);
pw.println('a');
pw.println("a");

//3.关闭
pw.close();
System.out.println("打印完毕");
转换流(内存中的字符与硬盘中的字节转换)

桥转换流 InputStreamReader/OutputStreamWriter

  • 可将字节流转换为字符流
  • 可设置字符的编码方式

InputStreamReader读取文件

//1.创建InputStreamWriter对象
FileInputStream fis = new FileInputStream("D:\\国家机密\\IO流\\write.txt");
InputStreamReader isr = new InputStreamReader(fis,"gbk");//读取文件,字符编码为GBK

//2.读取文件
int data = 0;
while ((data = isr.read()) != -1){
    System.out.print((char)data);
}

//3.关闭
isr.close();
System.out.println("读取完毕");

OutputStreamWriter写入文件

//1.创建OutputStreamWriter
FileOutputStream fos = new FileOutputStream("D:\\国家机密\\IO流\\info.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");//写入文件,字符编码为GBK

//2.写入
for(int i = 0; i < 10; i++){
    osw.write("我爱北京,我爱故乡\n");
    osw.flush();
}

//3.关闭
osw.close();
System.out.println("写入完毕");
File类(1.分隔符 2.文件操作 3. 文件夹操作)

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

方法:

方法名
mkdir()创建一个新目录
delete()删除文件或空目录
exists()判断File对象所代表的对象(文件)是否存在
getAbsolutePath()获取文件的绝对路径
getName()取得名字
getParent()获取文件/目录所再的目录
isDirectory()是否是目录
isFile()是否是文件
length()获得文件的长度
listFiles()列出目录中的所有内容
renameTo()修改文件名

分隔符

//(1) 分隔符
private static void separator() {
    System.out.println("路径分隔符" + File.pathSeparator);
    System.out.println("名称分隔符" + File.separator);
}

//输出结果
路径分隔符;
名称分隔符\

文件操作

//(2) 文件操作
    //1.创建文件 createNewFile()
    public static void fileOpe() throws Exception{
        File file = new File("D:\\国家机密\\IO流\\file.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退出时删除
//        file.deleteOnExit();
//        Thread.sleep(5000);   // 虚拟机待机5秒

    //3. 获取文件信息
        System.out.println("获取文件的绝对路径:" + file.getAbsoluteFile());
        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());

    }

//输出结果
获取文件的绝对路径:D:\国家机密\IO流\file.txt
获取路径:D:\国家机密\IO流\file.txt
获取文件名称:file.txt
获取父目录:D:\国家机密\IO流
获取文件长度:21
文件创建时间:2023312日 下午5:04:50
是否可写true
是否是文件true
是否隐藏false

文件夹操作

//(3) 文件夹操作
     public static void directoryOpe() throws Exception {
        //1.创建文件夹
        File dir = new File("D:\\国家机密\\IO流\\aa\\bb\\cc");
        //System.out.println(dir.toString());

        if (!dir.exists()){
            boolean c = dir.mkdirs();
            //mkdir 创建单级目录   mkdirs创建多级目录
            System.out.println(c);
        }

        //2. 删除文件夹(注意只能删除空目录)
        //2.1直接删除
      // System.out.println("删除结果为:" + dir.delete());

        //2.2 使用jvm删除
//        dir.deleteOnExit();
//        Thread.sleep(5000);

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

        //4. 判断
        System.out.println("是否是文件" + dir.isFile());
        System.out.println("是否隐藏" + dir.isHidden());

        //5. 遍历文件夹
        File dir2 = new File("D:\\国家机密\\IO流");
        String[] files = dir2.list();
        System.out.println("--------------------------------------");
        for (String string : files){
            System.out.println(string);
        }
         
         
//输出结果为
获取文件夹的绝对路径:D:\国家机密\IO流\aa\bb\cc
获取路径:D:\国家机密\IO流\aa\bb\cc
获取文件夹名称:cc
获取父目录:D:\国家机密\IO流\aa\bb
获取创建时间:2023312日 下午5:38:18
是否是文件false
是否隐藏false
--------------------------------------
1.jpg
2.jpg
aa
aaa.txt
bbb.txt
buffer.txt
file.txt
hello.txt
info.txt
IO1.md
print.txt
stu.bin
write.txt
FileFilter接口
  • public interface FileFilter
    • boolean accept(File pathname)
  • 当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件才可出现在listFiles()的返回值中
        File[] files2 = dir2.listFiles(new FileFilter() { //实例化FileFilter类
            //listFiles 遍历返回文件
            public boolean accept(File pathname) {
                if (pathname.getName().endsWith(".md")){   //如果文件后缀名为.md
                    return true;
                }
                return false;
            }
        });

        for (File file : files2){          //遍历文件数组
            System.out.println(file.getName());
        }


案例1: 递归遍历文件夹

public static void main(String[] args) {
    listDir(new File("D:\\国家机密"));    //实例化File传递地址给listDir方法
}

public static void listDir(File dir){
    File[] files = dir.listFiles();       //遍历文件夹赋值给files数组
    System.out.println(dir.getAbsolutePath());  //输出文件的绝对路径
    if (files!=null&&files.length>0){      //判断数组是否为空 且数组长度是否大于0
        for (File file : files){         //遍历数组
            if (file.isDirectory()) {     //判断是否为文件夹
                listDir(file);          //递归遍历文件夹
            }else {
                System.out.println(file.getName());  //输出文件名
            }
        }
    }
}

案例2:递归删除文件夹

//案例2  递归删除文件夹

public static void deleteDir(File dir) throws  Exception{
    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());
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值