Java基础 day14 I/O流

File类

在这里插入图片描述
文件可能存在也可能存在

File实例既可以是文件,又可以是文件夹

路径可以是绝对路径:包含盘符 相对路径:不包含盘符

构造方法
1.构造方法 pathname
2.构造方法 两个参数,父目录 文件名

文件操作

		//创建
        File file=new File("d:\\bb.txt");
        File file1=new File("d:\\","aaa.txt");
        if(!file1.exists()){
            boolean newFile = file1.createNewFile();
            System.out.println("创建成功");
        }
        else {
            System.out.println("文件已存在");
        }
        //文件删除
        //直接删除
        file1.delete();
        //jvm删除
        file1.deleteOnExit();
        //获取信息
        System.out.println("文件长度"+ file1.length());
        System.out.println("文件名称"+ file1.getName());
        System.out.println("文件绝对路径"+ file1.getAbsolutePath());
        System.out.println("规范路径"+file1.getCanonicalPath());
        System.out.println("文件路径"+file1.getPath());
        System.out.println("文件父目录"+file1.getParent());
        System.out.println("文件最后一次修改时间"+new Date(file1.lastModified()).toLocaleString());
        //判断
        System.out.println("是否存在"+file1.exists());
        System.out.println("是否只读"+file1.canWrite());
        System.out.println("是否隐藏"+file1.isHidden());
        System.out.println("是不是文件"+file1.isFile());
        System.out.println("是不是绝对路径"+file1.isAbsolute());
        //修改名称
        file1.renameTo(new File("d:\\chichi.txt"));

文件夹操作

		//1.创建
        File dir=new File("d:\\aa\\bb\\cc");
        if(!dir.exists()){
            dir.mkdirs();//创建多级目录
            System.out.println("文件删除成功");
        }else{
            System.out.println("目录已存在");
        }
        //2.删除
        //直接删除 只能删除最里层的空目录
        dir.delete();
        //JVM 删除
        dir.deleteOnExit();
        //3.信息获取
        System.out.println("获取路径"+dir.getPath());
        System.out.println("获取绝对路径"+dir.getAbsolutePath());
        System.out.println("获取名称"+dir.getName());
        System.out.println("规范名称"+dir.getCanonicalPath());
        //4.判断
        System.out.println("是否是文件夹"+dir.isDirectory());
        System.out.println("是否隐藏"+dir.isHidden());
        System.out.println("是否存在"+dir.exists());
        //5.重命名 具有剪切功能
        dir.renameTo(new File("d:\\aa\\bb\\hello"));
        //获取目录的子目录和文件
        File dir2=new File("d:\\aa");
        String[] list = dir2.list();//返回String数组
        for (String s : list) {
            System.out.println(s.toString());
        }

        File[] files = dir2.listFiles();
        for (File file : files) {
            System.out.println(file.toString());
        }
        
        //获取根目录
        File[] files1 = File.listRoots();
        for (File file : files1) {
            System.out.println(file.toString());
        }
FileFilter接口

在这里插入图片描述

//对获取文件进行过滤
        String[] txts = dir2.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {//文件和文件名
                if (name.endsWith("txt")) {
                    return true;
                }
                return false;
            }
        });
        for (String txt : txts) {
            System.out.println(txt);
        }

硬盘中所有数据都是二进制的

按照方向划分
输入流(读取):将存储设备中的内存读入到内存中
输出流(写入):将内存中的内容写到储存设备中

以内存为参照,进内存输入流,出内存输出流
读取,从外到内 写入 从内到外

流的分类

按单位: 字节流 字符流
按功能: 节点流 过滤流

通常用前两个

流使用后要close(方法)及时关闭

字节流

字节流的父类(抽象类):

输入流InputStream read方法
输出流OutputStream write方法

文件字节流

FileInputStream 文件字节输入流
FileOutputStream 文件字节输出流

文件不存在,会抛出异常,所以需要声明异常或者try catch

文件输入流
流下方法大部分需要抛出异常IOException

read方法
1.无参的 read 方法返回值为int类型,表示读入的一个字节的值,到流末尾时返回-1;
2. int read(byte[] bs)方法返回值表示读入的字节数,到流末尾时返回-1,参数表示读入的数据存放的位置。
3.int read(byte[] bs, int offset, int len)方法返回值表示读入的字节数,到流末尾时返回-1,参数分别表示读入的数据存放的位置,从哪个下表开始,最大
长度多少。

		public static void main(String[] args) throws IOException {
        FileInputStream input=new FileInputStream("chichi.txt");
        //读取多个字节
        byte[] buf=new byte[5];
        while (input.read(buf)!=-1){
            System.out.print(new String(buf));
        }
        input.close();
    }

文件输出流
构造方法

public FileOutputStream(String name,boolean append)
true表示追加,默认为false,覆盖

当多次添加时,请使append属性为true

write方法的对象文件:有则覆盖,无则创建

 FileOutputStream fileOutputStream = new FileOutputStream("chichi.txt", true);
        String s="赤赤,永远滴神,永远的300K\r\n";
        for (int i = 0; i < 10; i++) {
            fileOutputStream.write(s.getBytes());
        }
        fileOutputStream.close();
字节缓冲流

缓冲区大小默认为8k。
缓冲流把数据放入缓冲区中,靠文件字节流写入到硬盘中
在这里插入图片描述
调用write时,会把数据写入缓冲区,使用flush方法,可以刷新缓冲,或者使用close方法时,会自动关闭字节流并刷新缓冲
关闭缓冲流,自动关闭文件字节流

字节缓冲输入流
在这里插入图片描述

 		FileInputStream fileInputStream=new FileInputStream("chichi.txt");
        BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
        //读取
        //读取单个字节
        int data=0;
        while ((data=bufferedInputStream.read())!=-1){
            System.out.print((char) data);
        }

        //读取多个字节
        byte[] bytes = new byte[20];
        int len=0;
        while ((len=bufferedInputStream.read(bytes))!=-1){
            System.out.print(new String(bytes));
        }

字节缓冲输出流
在这里插入图片描述

FileOutputStream outputStream=new FileOutputStream("chichi.txt");
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);
        String s="chichi ssssssssssss";
        for (int i = 0; i < 10; i++) {
            bufferedOutputStream.write(s.getBytes());
        }
        bufferedOutputStream.flush();
        bufferedOutputStream.close();

try-with-resources 语句,自动释放资源,多个资源间用;隔开,释放时倒序释放,资源类要实现java.lang.AutoCloseable或java.io.Closeable接口,并重写close方法,否则会报错

public class Tryresourse {
    public static void main(String[] args) throws IOException {
        try (Person p=new Person();Chichi chi=new Chichi()){
        }
    }
}
class Person implements Closeable {

    @Override
    public void close() throws IOException {
        System.out.println("1关闭了");
    }
}
class Chichi implements Closeable{

    @Override
    public void close() throws IOException {
        System.out.println("2关闭了");
    }
}

输出:
在这里插入图片描述

对象流

ObjectOutputStream ObjectInputStream

需要靠文件字节输出流对硬盘读写
在这里插入图片描述

序列化:把对象写入到硬盘或网络的过程
反序列化:把硬盘或网络的二进制文件兑取到内存中形成对象的过程

student类实现标记接口Serializable list是student的集合

//创建对象流
ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("chichi.bin"));
//序列化
o.writeObject(list);
System.out.println("序列化成功");
o.close();
//反序列化
ObjectInputStream i=new ObjectInputStream(new FileInputStream("chichi.bin"));
ArrayList<Student> list1=(ArrayList) i.readObject();//读出的是Object类型,需要强制类型转换

要求
1.序列化的类必须实现Serializable(自动序列化接口,标记接口,内部无方法),Externalizable(手动序列化接口,内部两个方法需要重写)
2.序列化的类要添加一个私有的long类型常量:serialVersionUID,保证序列化的类和反序列的类是同一个类 ,不同报错
private static final longserialVersionUID 会自动生成,也可手动添加

注意实现
不会调用构造方法
1.使用transient修饰的属性,不会被序列化(反序列化时属性名还在,但值不在)
2.静态属性不能序列化(反序列化时值还在,因为静态属性是类的属性)

读到文件尾部的标志:java.io.EOFException

面试题:使用transient的属性一定不能序列化吗?
能,实现Externalizable接口并重写方法

class Student implements Externalizable{
     transient String name;
     static int age;

    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        // ObjectOutput时对象流的父接口
        out.writeObject(name);//写入
        out.writeObject(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name =(String) in.readObject();//强制转换读出
        age=(int)in.readObject();
    }

----------------------------------------------------------------------------

字符编码

在这里插入图片描述
UTF-8可能是1或2,或3个字节

一个中文UTF-8 是三个字节 在JAVA内部内存中是两个字节

字符流

Reader Writer(抽象类)

使用char数组读取
在这里插入图片描述

在这里插入图片描述

文件字符流

FileReader FileWriter

字符缓冲流

不能直接对硬盘读写功能,要借助文件字符流()

BufferedReader BufferedWriter

支持输入换行符,可一次写一行,读一行

写:特有newLine()方法,可以实现跨平台换行,写完后必须加上这句话,并flush刷新

读:readline() 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

public static void main(String[] args)  throws IOException {
        //缓冲输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("chichi.txt"));
        for (int i = 0; i < 5; i++) {
            bw.write("chichi yyds");
            bw.newLine();//特有方法,实现换行
            bw.flush();
        }
        bw.close();
        //缓冲输出流
        BufferedReader br = new BufferedReader(new FileReader("chichi.txt"));
        String data=null;
        while ((data=br.readLine())!=null){
            System.out.println(data);//返回字符串,末尾反null
        }
        br.close();
    }

转换流

文件字符流父类

第一个参数构造函数均为字节流

InputStreamReader:字节流通向字符流的桥梁 (硬盘->内存)
在这里插入图片描述
在这里插入图片描述

  //1创建输入转换流
        FileInputStream fis=new FileInputStream("d:\\trans.txt");
        InputStreamReader isr=new InputStreamReader(fis,"utf-8");

OutputStreamWriter:字符流通向字节流的桥梁 (内存->硬盘)

在这里插入图片描述
在这里插入图片描述

		//创建输出转换流
  		FileOutputStream fos=new FileOutputStream("d:\\trans.txt");
        OutputStreamWriter osw=new OutputStreamWriter(fos,"GBK");

通过charsetName可设置字符的编码方式

打印流

永远不会抛出 IOException,有缓冲区

PrinterStream 字节打印流
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PrinterWriter 字符打印流

print方法与write方法的区别
print方法原样打印,看到的是什么,打印出来的就是什么

		PrintStream ps=new PrintStream("chichi.txt");
        ps.println(97);//写入97 原样打印
        PrintWriter pr=new PrintWriter("chichi.txt");
        pr.write(97);//写入a,
        pr.close();
重定向标准输出流

setOut参数 为 字节打印流

在这里插入图片描述
out是一个字节打印流
in是一个字节输入流

 		//简单实现Scanner
        InputStreamReader iSR = new InputStreamReader(System.in);//转字符流
        BufferedReader br = new BufferedReader(iSR);
        String data=br.readLine();
        br.close();
        System.out.println(data);

RandomAccessFile随机流

在这里插入图片描述
在这里插入图片描述

又能写又能读各种常见类型

 //写入
        RandomAccessFile file=new RandomAccessFile("chichi.txt","rw");
        file.writeUTF("chichi");
        file.writeInt(19);
        file.writeDouble(130.0);
        file.close();
        //读取  还是要创建两个对象的
        RandomAccessFile file1=new RandomAccessFile("chichi.txt","rw");
        file1.seek(8);//从开头位置设置文件指针的偏移量
//        System.out.println(file1.readUTF());
//        file1.skipBytes(8);//跳过字节个数,从当前位置跳
        System.out.println(file1.readInt());
        System.out.println(file1.readDouble());
        file1.close();

一个字符一字节,
00 06(UTF的固定开头) 63 c 68 h 69 i
int型4字节
00 00 00 13 19
double 8字节 40 60 40 00 00 00 00 00

在这里插入图片描述

Properties集合

在这里插入图片描述
1.list()遍历,输出到流中,用于打印信息
2.store()保存 到把文件 要求不用中文用字节输出流,可以中文用字符输出流
3.load() 加载文件
在这里插入图片描述
在这里插入图片描述

		Properties properties1 = new Properties();
        Properties properties = properties1;
        properties.setProperty("name","zhang");
        properties.setProperty("password","123");
        //list遍历,输出到流
        properties.list(System.out);
        PrintStream writer = new PrintStream("chichi.txt");
        properties.list(writer);
        writer.close();
        //store 保存文件  汉字会存储为编码
        FileWriter file = new FileWriter("chichi.txt");
        properties.store(file,"用户信息");
        //load 加载文件
        Properties properties2 = new Properties();
        FileReader fileReader = new FileReader("chichi.txt");
        properties2.load(fileReader);
        fileReader.close();
        properties2.list(System.out);

总结

在这里插入图片描述
本质上说没有字符流,字符流内部用的都是字节流,不过采用了特定编码转换

除了文件字节流其他流都有缓存,所以这些有缓冲的流如果不用flush或close方法刷新缓冲,将会无法写入(可通过flush方法测试,有此方法的都有缓冲)

read返回读取的字符数,如果已到达流的末尾,则返回 -1
BufferedReader的readLine,到达末尾的返回值是null,遇到换行符才会返回,没有换行符会卡死,不在继续向进行

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值