File类和IO流

1 篇文章 0 订阅

参考:JAVA开发从入门到精通

代码demo

一、File类

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

package com.test.file;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

public class FileDemo {
    public static void main(String[] args) throws IOException {
        // 输出File类中属性的值,常量值,
        String str = File.separator;
        System.out.println(File.separator);          //输出结果:\  -->字符串形式
        System.out.println(File.separatorChar);      //输出结果:\  -->字符形式
        System.out.println(File.pathSeparator);      //输出结果:;
        System.out.println(File.pathSeparatorChar);  //输出结果:;

        // File类的构造器,三种构造方式
        //第一种构造方式
        File file = new File("E:/test.txt");   // 或者File file = new File("E:\\test.txt");
        System.out.println(file);   // 输出结果:  E:\test.txt
        //第二种构造方式
        File file2 = new File("E:", "test.txt"); //或者File file2 = new File("E:\\", "test.txt");
        System.out.println(file2);  // 输出结果:  E:\test.txt
        //第三种构造方式
        File file3 = new File("E:"); //或者File file3 = new File("E:\\");
        File file4 = new File(file3, "test.txt");
        System.out.println(file4);  // 输出结果:  E:\test.txt

        System.out.println(file.length());   //输出字节长度,中文占3个字符,中文标点符号也是3个字符,英文占用一个字符
        //比如test.txt里面的内容为:您好        file.length()为:6
        //比如test.txt里面的内容为:您好!       file.length()为:9
        //比如test.txt里面的内容为:aaa         file.length()为:3

        System.out.println(file.canRead());   //文件是否可读
        System.out.println(file.canWrite());  //文件是否可写

        File createFile = new File("E:\\test2.txt");
        if (! createFile.exists()) {//  exists()判断文件是否存在
            boolean createNewFile = createFile.createNewFile();   //创建新文件
            System.out.println(createNewFile);
        }

        if(createFile.exists()) {
            boolean delete = createFile.delete();  //删除文件
            System.out.println(delete);
        }

        System.out.println(file.isFile());      //是否为文件
        System.out.println(file.isAbsolute());  //是否为绝对路径
        System.out.println(file.isDirectory()); //是否为目录
        System.out.println(file.isHidden());    //是否隐藏

        System.out.println(new Date(file.lastModified()));  //最后一次修改的时间秒数  输出结果为:Wed May 19 12:58:40 CST 2021

        File file5 = new File("E:\\360Downloads");
        if (file5.isDirectory()) {
            File[] listFiles = file5.listFiles();  //获取列表的文件对象
            System.out.println(listFiles.length);
            /**
             * 输出结果:
             * E:\360Downloads\Software
             * E:\360Downloads\wpcache
             */
            for (File f : listFiles) {
                System.out.println(f);
            }
        }

        if (file5.isDirectory()) {
            String[] strList = file5.list();   //获取列表的名称
            /*
             *第一种输出,一个个输出
             * 输出结果:
             * Software
               wpcache
             */
            for(String s : strList) {
                System.out.println(s);
            }
            /*第二种输出,直接全部输出
             * 输出结果:
             * [Software, wpcache]
             */
            System.out.println(Arrays.toString(strList));
        }

        if (file5.isDirectory()) {
            File[] rootFile = file5.listRoots();  //获取磁盘的根目录对象
            /**
             * 输出结果:
             * C:\
             * D:\
             * E:\
             */
            for (File root : rootFile) {
                System.out.println(root);
            }
        }

        File f6 = new File("E:\\aa");
        if (!f6.exists()) {
            System.out.println(f6.mkdir());  // 创建单层文件夹
        }

        File f7 = new File("E:\\aa\\bb");
        if (!f7.exists()) {
            System.out.println(f7.mkdirs());  // 创建多层文件夹
        }

        String name = f7.getName();  //获取文件名称
        System.out.println(name);  //输出结果为:bb
    }
}

二、 I/O流

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

三、文件字节输入输出流

在这里插入图片描述

InputStream、OutputStream这两个类是抽象类。

在这里插入图片描述

package com.test.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class FileInputStreamDemo {
    public static void main(String[] args) {
        try {
            // 创建FileInputStream对象
            FileInputStream in = new FileInputStream("E:\\test.txt");
            // 通过文件对象进行创建
            File file = new File("E:\\test.txt");
            FileInputStream in2 = new FileInputStream(file);
            //读取文件 test.txt的内容为:hello world!
            int i = in.read();
            System.out.println(i);       //输出结果:104
            System.out.println((char)i); //输出结果:h
            byte[] b = new byte[1024];
            int read = in.read(b);
            System.out.println(read + " : " + new String(b));  //输出结果:11 : ello world!,因为流是顺序读取,上面执行in.read()操作读了一个字节"h"

            in.close();  //关闭流操作,不然会造成内存泄露
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

package com.test.file;

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

public class FileOutputStreamDemo {
    public static void main(String[] args) {
        try {
            // 创建文件输出流对象
            //FileOutputStream out = new FileOutputStream("E:\\test.txt");
            FileOutputStream out = new FileOutputStream("E:\\test.txt", true);   //后面的参数true表示是否在文件尾部追加内容
            //往文件中写入内容
            out.write(97);  //往test.txt文件中写入一个字节a
            out.write("hello world!".getBytes());   //往test.txt文件中写入"hello world!"
            out.close();      //关闭输出流
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


四、对象字节输入输出流

谈谈实现Serializable接口的作用和必要性
对象的序列化:
把对象转换成二进制的形式,成为对象的序列化
对象序列化的实现方式: 在定义实体类的时候实现序列化接口即可。

反序列化
把二进制转换成对象的形式

字节流:针对二进制的处理
ObjectInputStream:对象字节流入流

读取对象:把文件中的数据以二进制的形式进行读取,然后转换成Object对象进行输入到程序。

ObjectOutputStream:对象字节输出流
把程序中的实体类对象的值输入到文件中。
在这里插入图片描述
创建一个类必须要实现Serializable序列化接口
QQ.java

package com.test.file;

import java.io.Serializable;

public class QQ implements Serializable {
    private int QQ;
    private String nickName;
    // transient瞬时态,添加该关键字的变量是不会被序列化出去的
    //private transient String nickName;
    private String sex;
    private String note;

    public int getQQ() {
        return QQ;
    }

    public void setQQ(int QQ) {
        this.QQ = QQ;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    @Override
    public String toString() {
        return "QQ{" +
                "QQ=" + QQ +
                ", nickName='" + nickName + '\'' +
                ", sex='" + sex + '\'' +
                ", note='" + note + '\'' +
                '}';
    }
}

ObjectInOutputStremDemo.java

package com.test.file;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class ObjectInOutputStremDemo {
    public static void main(String[] args) {

        try {
            //序列化
            OutputStream out = new FileOutputStream("E:\\test.txt");
            //创建对象字节输出流对象
            ObjectOutputStream oos = new ObjectOutputStream(out);
            QQ qq = new QQ();
            qq.setQQ(111111);
            qq.setNickName("test");
            qq.setSex("男");
            qq.setNote("备注");
            oos.writeObject(qq);
            oos.writeBoolean(true);
            oos.writeLong(1000);
            oos.writeByte('a');
            oos.writeBytes("hello world!");
            oos.flush();
            oos.close();
            out.close();

 			//反序列化
            //创建对象字节输入流对象
            InputStream in = new FileInputStream("E:\\test.txt");
            ObjectInputStream ois = new ObjectInputStream(in);
            Object obj = ois.readObject();
            /**
             * 特别注意,write写入的类型顺序与read读取的类型顺序需要一致,否则读取的数据会出错
             */
            System.out.println(obj);                 //输出结果:QQ{QQ=111111, nickName='test', sex='男', note='备注'}
            /**
             * 如果nickName字段属性被设置为transient,则该字段是不会被序列化的
             * private transient String nickName;
             */
            //System.out.println(obj);                 //输出结果:QQ{QQ=111111, nickName='null', sex='男', note='备注'}

            System.out.println(ois.readBoolean());   //输出结果:true
            System.out.println(ois.readLong());      //输出结果:1000
            //System.out.println(ois.readByte());      //输出结果:97
            System.out.println((char)ois.readByte());//输出结果:a
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = ois.read(b)) != -1) {
                System.out.println(new String(b, 0, len));     //输出结果:hello world!
            }
            in.close();
            ois.close();

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}


五、 文件字符输入输出流

在这里插入图片描述
Reader、Writer这两个类为抽象类

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

package com.test.file;

import java.io.FileNotFoundException;
import java.io.FileReader;

public class FileReaderDemo {
    public static void main(String[] args) {
        try {
            // 创建字符输入流对象
            FileReader fr = new FileReader("E:\\test.txt");
            // test.txt文件中的内容为:aaabbbccc
            int read = fr.read();
            System.out.println((char)read);  //输出结果:a
            int read2 = fr.read();
            System.out.println((char)read2); //输出结果:a
            char[] chars = new char[1024];
            int len = fr.read(chars);
            while (len != -1) {
                System.out.println(new String(chars)); //输出结果:abbbccc
                len = fr.read(chars);
            }
            fr.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

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

package com.test.file;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo {
    public static void main(String[] args) {
        try {
            // 创建文件写入对象
            // FileWriter fw = new FileWriter("E:\\test.txt");
            FileWriter fw = new FileWriter("E:\\test.txt", true);
            fw.write("hello world!");
            fw.flush();  //刷新缓存流
            fw.close();  //关闭流
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

六、文件复制

1、通过文件字节流进行复制
2、通过字符流进行复制

package com.test.file;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 文件复制:
 * 1. 通过文件字节流进行复制
 * 2. 通过字符流进行复制
 * 要求:把test.txt文件中的内容复制到test2.txt中
 */
public class FileCopy {
    public static void main(String[] args) throws IOException {
        /*
         * 1.创建test2.txt文件
         * 2.读取test.txt文件中的内容
         * 3.把读取的内容写入到test2.txt文件中
         */

        File file = new File("E:\\test2.txt");
        if (!file.exists()) {
            file.createNewFile();
        }

        FileReader fr = new FileReader("E:\\test.txt");
        FileWriter fw = new FileWriter(file);
        char[] chars = new char[1024];
        int len = fr.read(chars);
        while (len != -1) {
            fw.write(chars, 0, chars.length);
            len = fr.read(chars);
        }
        fw.flush();
        fw.close();
        fr.close();

    }
}

七、RandomAccessFile

RandomAccessFile 很重要的功能用于多线程中分段下载

构造方法
RandomAccessFile raf = new RandomAccessFile(File file, String mode);
其中参数mode的值可选“r”:可读,“w”:可写,“rw”:可读写

成员方法:
seek(int index):可以将指针移动到某个位置开始读写
setLength(long len):给写入文件预留空间

RandomAccessFile特点和优势

  1. 既可以读也可以写
    RandomAccessFile不属于InputStream和OutputStream类系的,它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是自己从头开始规定的,这里面包含读写两种操作

  2. 可以指定位置读写
    RandomAccessFile能在文件里面前后移动,在文件里移动用seek(),所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继续Object的独立的类。只有RandomAccessFile才有seek搜索方法,而这个方法也只适用于文件。

8、NIO——FileChannel

Channel是对I/O操作的封装
FileChannel配合着ByteBuffer,将读写的数据缓存到内存中,然后以批量/缓存的方式read/write,省去了非批量操作时的重复中间操作,操作大文件时可以显著提高效率(和Steam以byte数组方式有什么区别?经过测试,效率上几乎无区别)

问题1:字节流和字符流的区别?
答:FileOutputStream: 字节流输出,它是一个字节一个字节向外边送数据
OutputStreamWriter:字符流,它是一个字符一个字符的向外边送数据
因为计算机是外国人发明,它们的英文字符占一个字节,而我们的中文是一个字符,至少占两个字节,如果用stream,你读出来的英文是正常的,但是如果读出来的中文就会出现乱码或者一个个“???”,如果用Writer,就不会有乱码

问题2:BufferedWriter buffer是一个缓冲区,为什么要用Buffer呢?
答:如果你直接使用stream或者writer,你的硬盘可能就是读一个字符或者一个字节,就去读写硬盘一次,IO负担巨大。可能你用了buffer,你的硬盘就是读了一堆数据之后,读写一下硬盘。这样对硬盘有好处。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值