java I/O

1.1教学目标

  1. 流的概念
  2. 流的分类
  3. 字节流
  4. 编码方式
  5. 字符流
  6. File类

1.2 什么是流

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

1.3 流的分类

按方向(重点)

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

按单位:

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

按功能

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

1.4字节流

  1. 字节流的父类(抽象类):
    • InputStream:字节输入流
    • OutputStream:字节输出流
      在这里插入图片描述在这里插入图片描述

文件字节流

  1. FileInputStream:从文件系统中的某个文件中获得输入字节。哪些文件可取决于主机环境。

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

package IO;

import java.io.FileInputStream;
import java.util.Arrays;
import java.util.List;

public class FileInput {
    public static void main(String[] args) throws Exception {
        //1创建FileInputSteam,并指定文件路径
        FileInputStream file = new FileInputStream("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/1.txt");
//        //2.1 读取文件,每读一个打印一个,单个字节打印
//        int data=0;
//        while ((data=file.read()) !=-1){
//            System.out.print(data);//读出来ASCII码,如231,252,97等
//            System.out.print(" "+(char) data);//强转换,可以转成char
//
//        }
        //2.2 一次读取多个字节。即传入一个数组,这个数据作为留接收器,保存
//        byte[] by = new byte[3];
//        int count = file.read(by);
//        System.out.println(new String(by));//abc
//        System.out.println(count);//3
        //2.3 用while循环读数组
        byte[] buf = new byte[3];
        int count = 0;
        while ((count = file.read(buf)) != -1) {
            System.out.println(new String(buf));
        }

        //3 关闭。
        file.close();
        System.out.println("执行关闭");

    }
}
  1. FileOutputStream:

    一次写多个字节,将b数组中所有字节,写入输出流。

package IO;

import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

public class FileOut {
    public static void main(String[] args) throws Exception {
        //1创建文件字节输出流对象
        FileOutputStream file = new FileOutputStream("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/2.txt");
        file.write(97);
        file.write('b');
        file.write('c');
        String a="你好啊";
        file.write(a.getBytes());
        file.close();
    }
}

字节流复制文件

package IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

public class FileOut {
    public static void main(String[] args) throws Exception {
        //1 创建流
        //1.1 文件字节输入流
        FileInputStream filein = new FileInputStream("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/2.jpg");
        //1.2 文件字节输出流
        FileOutputStream fileout = new FileOutputStream("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/2-copy.jpg");
        //2一边读,一边写
        byte[] buf=new byte[1024];
        int count = 0;
        while ((count=filein.read(buf))!=-1){
            fileout.write(buf,0,count);//因为有些末尾不是-1的,会保留,所以要用这个
        }
        filein.close();
        fileout.close();
    }
}

字节缓冲流

  1. 缓冲流:BufferedInputStream/BufferedOutputStream
    • 提高IO效率,减少访问磁盘的次数。
    • 数据存储在缓冲区中,flush 是将缓存区的内容写入文件中,也可以直接close。
//BufferedInputStream
package IO;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class FileOut {
    public static void main(String[] args) throws Exception {
        //1创建BufferedInputStream
        FileInputStream file = new FileInputStream("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/1.txt");
        BufferedInputStream bufile = new BufferedInputStream(file);
        //2读取
        int data=0;
        while ((data=bufile.read()) != -1){
            System.out.println((char)data);
        }
        //3 关闭
        bufile.close();
    }
}
//BufferedOutputStream
package IO;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class FileOut {
    public static void main(String[] args) throws Exception {
        //1创建字节输出缓冲流
        FileOutputStream fileout = new FileOutputStream("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/3.txt");
        BufferedOutputStream bufileout = new BufferedOutputStream(fileout);
        //2写入文件
        for (int i = 0; i < 10; i++) {
            bufileout.write("hello".getBytes());
            bufileout.flush();//刷新到本地的硬盘
        }
//        bufileout.close();//也可以直接关闭
    }
}

1.5对象流

对象流:ObjectOutputStream/ObectInputStream

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

使用流传输对象的过程称为序列化,反序列化。

序列流

//Student类 class 必须 加上 implements Serializable
package IO;

import java.io.*;
import java.nio.charset.StandardCharsets;
import base.Student;
import base.Student;

public class FileOut {
    public static void main(String[] args) throws IOException {
        //1 创建流
        FileOutputStream fos = new FileOutputStream("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //2 序列化(写入操作)
        Student s1 = new Student("张三","12");
        Student s2 = new Student("李四","14");
        oos.writeObject(s1);
        oos.writeObject(s2);
        //3 关闭
        oos.close();


    }
}

反序列化

import base.Student;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectInput {
    public static void main(String[] args) throws Exception {
        //1创建流
        FileInputStream file = new FileInputStream("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.bin");
        ObjectInputStream ois = new ObjectInputStream(file);
        //2读取文件(反序列化)
        Student s = (Student) ois.readObject();
        //3 关闭
        ois.close();
        System.out.println(s.toString());

    }
}

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

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

  2. 序列化类中对象属性要求实现Serializable接口
    private static final long serialVersionUID = 1L;
    serialverisonUID 是序列化版本号ID,保证序列化的类和反序列化是同一个类

  3. 使用transient 修饰属性,这个属性不可以序列化

  4. 静态属性不能书序列化

  5. 序列化多个对象,可以借助集合实现

1.6 字符编码

  1. ISO-8859-1收录除ASCII外,还包括秀,希腊语,泰语,阿拉伯语,希伯来语对应的文字符号。

  2. UTF-8针对Unicode码表的可变长度字符编码。 1、2、3个字节

  3. GB2312 简体中文 ;1个字节或者2个字节

  4. GBK 简体中文、扩充

  5. BIG5 台湾,繁体中文

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

1.7 字符流

  1. 字符流的父类(抽象类)
    • Reader:字符输入流
    • Writer:字符输出流
      在这里插入图片描述

文件字符流

  1. FileReader:

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

package IO;

import base.Student;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.ObjectInputStream;

public class ObjectInput {
    public static void main(String[] args) throws Exception {
        //1 创建FileReader 文件字符输入流
        FileReader fr = new FileReader("/Users/tianzhi/Library/CloudStorage/OneDrive-zjnu.edu.cn/MarkDown/java/1.txt");
        //2 读取
        //2.1 单个字符读取
//        int data=0;
//        while ((data=fr.read()) !=-1){
//            System.out.print((char) data);
//        }
        //2.2 数组读取
        char[] ch = new char[1024];
        int num = 0;
        while ((num=fr.read(ch))!=-1){
            System.out.println(new String(ch,0,num));
        }
        System.out.println("===");
        }
    }
  1. FileWriter:

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

package IO;

import base.Student;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.ObjectInputStream;

public class ObjectInput {
    public static void main(String[] args) throws Exception {
        //1 创建FileWrite对象
        FileWriter fw = new FileWriter("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.txt");
        //2 写入
        for (int i = 0; i < 10; i++) {
            fw.write("你好啊\r\n");
            fw.flush();
        }
        fw.close();
    }
}

字符流复制文件

package IO;

import base.Student;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.ObjectInputStream;

public class ObjectInput {
    public static void main(String[] args) throws Exception {
        //1 创建对象
        FileReader fr = new FileReader("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.txt");
        FileWriter fw = new FileWriter("/Users/tianzhi/IdeaProjects/untitled/src/IO/1-copy.txt");
        //2 读写
        int data=0;
        while ((data=fr.read())!=-1){
            fw.write(data);
            fw.flush();
        }
        fr.close();
        fw.close();
    }
}

字符缓冲流

  1. 缓冲流:BufferedReader/BufferedWriter
    • 高效读写
    • 支持输入换行符。
    • 可一次写一行,读一行。
//BufferedReader
package IO;

import base.Student;

import java.io.*;

public class ObjectInput {
    public static void main(String[] args) throws Exception {
        //1 创建对象
        FileReader fr = new FileReader("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.txt");
        BufferedReader br = new BufferedReader(fr);
        //2.2 单个读写
//        int data=0;
//        while ((data=br.read())!=-1){
//            System.out.print((char)data);
//        }
        //2.2 多个读写
//        char[] buf= new char[1024];
//        int count=0;
//        while ((count=br.read(buf))!=-1){
//            System.out.println(new String(buf,0,count));
//        }
        //2.3 一行一行读写
        String line = null;
        while ((line=br.readLine()) !=null){
            System.out.println(line);
        }
        br.close();
        fr.close();
    }
}

//BufferedWiter
package IO;

import base.Student;

import java.io.*;

public class ObjectInput {
    public static void main(String[] args) throws Exception {
        //1 创建对象
        FileWriter fw = new FileWriter("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        //2 写入
        for (int i = 0; i < 10; i++) {
            bw.write("好好学习,天天向上");
            bw.newLine();//写入一个换行符 win \r\n   linux \n
        }
        //3 关闭
        bw.close();
    }
}

1.8打印流

  1. PrinterWriter

    • 封装了print() / println() 方法,支持写入后换行

    • 支持数据原样打印

1.9 转换流

桥转换流: InputStreamReader OutputSteamWriter

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

InputStreamReader:是字节流通向字符流的桥梁。把硬盘的字节写入到内存中。

package IO;

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

public class FileInput {
    public static void main(String[] args) throws Exception {
        //创建流
        FileInputStream fis = new FileInputStream("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.txt");
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        //读取文件
        int count=0;
        while ((count=isr.read())!=-1){
            System.out.println(count);
        }
        //关闭
        isr.close();
    }
}

OutputSteamWriter:是字符流通向字节流的桥梁。把内存的字符写入到硬盘上。

package IO;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class FileInput {
    public static void main(String[] args) throws Exception {
        //1创建OutputStreamWriter
        FileOutputStream fos = new FileOutputStream("/Users/tianzhi/IdeaProjects/untitled/src/IO/1-copy3.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
        //2 写入
        for (int i = 0; i < 10; i++) {
            osw.write("我爱北京");
            osw.flush();
        }
        osw.close();
    }
}

2.0 File类

  1. 概念:代表物理盘符中的一个文件或者文件夹。
  2. 方法
createNewFile()//创建一个新文件
mkdir()//创建一个新目录
delete()//删除文件或者空目录
existes()//判断File对象所对象所代表的对象是否存在
getAbsolutePate()//获取文件的绝对路径
getName()//获取名字
getParent()//获取文件/目录所在的目录
idDirectory()//是否是目录
isFile()//是否是文件
length()//获取文件的长度
listFiles()//列出目录中的所有内容
renameTo()//修改文件名为
//文件操作
package IO;

import java.io.File;
import java.io.IOException;
import java.util.Date;

public class FileDemo {
    public static void main(String[] args) throws IOException, InterruptedException {
        //1 分隔符
        System.out.println("路径分隔符" + File.pathSeparator);
        System.out.println("名称分隔符" + File.separator);
        //2 文件操作
        //2.1 创建文件
        File file = new File("../3.txt");
        System.out.println(file.toString());//   路径/Users/tianzhi/IdeaProjects/untitled/src/IO/2.txt
        if (!file.exists()) {
            boolean b = file.createNewFile();
            System.out.println("创建文件结果" + b);
        }
        //2.2删除文件
//        boolean del = file.delete();
//        System.out.println("删除结果"+del);
//        Thread.sleep(5000);
        //2.2.2使用jvm退出时删除
//        file.deleteOnExit();
        //3获取文件信息
        System.out.println("获取文件的绝对路径"+file.getAbsoluteFile());//获取绝对路径/Users/tianzhi/IdeaProjects/untitled/3.txt
        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.canRead());
        System.out.println("是否是文件"+file.isFile());
        System.out.println("是否隐藏"+file.isHidden());
    }

}
//文件夹操作
package IO;

import java.io.File;
import java.io.IOException;
import java.util.Date;

public class FileDemo {
    public static void main(String[] args) throws Exception {
        //1创建文件夹
        File dir = new File("/Users/tianzhi/IdeaProjects/untitled/src/IO/ces");
        System.out.println(dir.toString());
        if (!dir.exists()) {
            System.out.println("创建结果" + dir.mkdir());//只能创建单级目录
//            dir.mkdirs();//创建多级目录
        }
        //2删除文件夹
//        System.out.println("删除结果"+dir.delete());//注意删除空目录
//        //2.1 使用jvm删除
//        dir.deleteOnExit();
        //3 获取文件夹信息,同文件。这里不不写了
        System.out.println("获取文件夹的绝对路径" + dir.getAbsoluteFile());//获取绝对路径/Users/tianzhi/IdeaProjects/untitled/3.txt
        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.isDirectory());
        System.out.println("是否隐藏" + dir.isHidden());
        //5遍历文件夹
        File dir2 = new File("");//设定为当前目录
        String[] files = dir2.listFiles();
        for (String x : files) {
            System.out.println(x);
        }
    }

}

2.1 FileFilter接口

public interface FileFilter
  boolean accept(File pathname)

当调用File类中的listFiles()方法时,支持传入FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFiles()的返回值中。

        File[] out = dir2.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.getName().endsWith(".jpg")) {
                    return true;
                }
                return false;
            }
        });
        for (File file:out){
            System.out.println(file.getName());
        }

2.2 递归遍历和递归删除

递归遍历文件夹

package IO;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Date;

public class FileDemo {
    public static void main(String[] args) throws Exception {
        deleteDir(new File("/Users/tianzhi/IdeaProjects/untitled/src/IO/ces"));

    }

  //遍历文件夹
    public static void listDir(File dir) {
        File[] files = dir.listFiles();
        if (files != null && files.length > 0)
            for (int i = 0; i < files.length; i++) {
                if (!files[i].isDirectory()) {
                    System.out.println(files[i].getName() + files[i].getAbsoluteFile());
                }else {
                    listDir(new File(files[i].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.getAbsoluteFile()+"删除"+file.delete());
             }
         }
        }
        dir.delete();


    }
}

2.3 Properties

Properties:属性集合

特点:

      	1. 存储属性名和属性值
      	2. 属性名和属性值都是字符串类型
      	3. 没有泛型
      	4. 和流有关
package IO;

import java.io.*;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import static java.lang.System.out;

public class FileDemo {
   public static void main(String[] args) throws IOException {
       //1创建集合
       Properties properties = new Properties();
       //2添加数据
       properties.setProperty("username","zhangsan");
       properties.setProperty("age","20");
       out.println(properties.toString());
       //3遍历
       out.println("====方法1");
       for (Object x:properties.keySet()){
           out.println((String) x);
       }
       out.println("=====方法2");
       Set<Map.Entry<Object, Object>> entries = properties.entrySet();
       for (Map.Entry<Object,Object> x: entries){
           out.println(x.getKey()+":"+x.getValue());
       }
       //3.3------stringProperyNames()---
       Set<String> pro = properties.stringPropertyNames();
       for (String x:pro){
           out.println(x+":"+properties.getProperty(x));
       }
       //4 和流有关的方法
       //----list-----
       PrintWriter printWriter = new PrintWriter("/Users/tianzhi/IdeaProjects/untitled/src/IO/1.txt");
       properties.list(printWriter);
       printWriter.close();
       //5 2 store 保存
       FileOutputStream fot = new FileOutputStream("/Users/tianzhi/IdeaProjects/untitled/src/IO/1-stream.txt");
       properties.store(fot,"注释");
       fot.close();
       //5 load加载办法
       Properties proper = new Properties();
       FileInputStream fileinputstream = new FileInputStream("/Users/tianzhi/IdeaProjects/untitled/src/IO/1-stream.txt");
       proper.load(fileinputstream);
       System.out.println(proper);

   }
}

2.4总结

  1. 流的概念:内存与存储设备之间传输数据的通道。
  2. 流的分类:输入流、输出流;字节流,字符流;节点流、过滤流
  3. 序列化、反序列化:
  4. 将对象通过流写入到文件,或将回想通过流读取到内存,必须实现Serializable接口
  5. File对象:代表物理盘符的文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值