Java IO流以及File类

目录

File类概述

File类常用方法

IO流

io流分类 

Writer字符输出流

覆盖写入

追加写入

Reader字符输入流

字节流

字节输出流

覆盖写入

字符输入流

文件的拷贝

  字符流文件的拷贝

字节流文件拷贝

字节流缓冲区

缓存流

字节缓存流

字节缓存输出流

字节缓存输入流 

字符缓存输出流

字符缓存输入流

使用字节缓存输入输出流拷贝文件

对象流--对java对象进行IO操作

序列化与反序列化


File类概述

io流可以对文件内容进行读写操作,而其中的File类对文件本身进行操作,比如创建文件、删除文件、重命名文件、等操作。该类封装了一个路径,并提供了一系列方法用于操作该路径指向的文件。

File类位于java.io包中。

File类常用方法

Java IO流以及File类_第1张图片

Java IO流以及File类_第2张图片

public class Add {
    public static void main(String[] args) throws IOException {
        //创建目录
        File f = new File("F:/java151/FileTest/YTR");
        f.mkdir();
        //创建文件
        File f2 = new File("F:/java151/FileTest/YTR/Text.txt");
        f2.createNewFile();
        for(int i = 9;i<=13;i++){
            File f3 = new File("F:/java151/FileTest/YTR/Text" + i + ".txt");
             f3.createNewFile();
        }
        //创建多级目录
        File f4 = new File("F:/java151/FileTest/YTR/ytr/aaa");
        f4.mkdirs();

        //查询
        //查询文件名
        String s1 = f2.getName();
        System.out.println(s1);
        //查询文件夹名
        String s2 = f.getName();
        System.out.println(s2);
        //查询文件路径
        String s3 = f.getPath();
        System.out.println(s3);
        //查询父级文件路径
        String s4 = f.getParent();
        System.out.println(s4);
        //判断是否为文件
        boolean b = f.isFile();
        System.out.println(b);
        //判断是否为目录
        boolean b2 = f.isDirectory();
        System.out.println(b2);
        //判断文件是否可读
        boolean b3 = f2.canRead();
        System.out.println(b3);
        //判断文件是否可写
        boolean b4 = f2.canWrite();
        System.out.println(b4);
        //判断文件或目录是否存在。
        boolean b5 = f2.exists();
        System.out.println(b5);
        //列出指定目录下所有子文件名包括目录名
        String[] arr = f.list();
        System.out.println(Arrays.toString(arr));
        //列出指定目录下所有子文件包括目录的完整路径
        File[] arr2 = f.listFiles();
        System.out.println("+++++++"+arr2[2].toString());
        System.out.println(Arrays.toString(arr2));
        for (File file: arr2) {
            //获取文件名和目录名
            System.out.println(file.getName());
            //获取完整路径
            System.out.println(file.toString());
        }
    }
}

 输出目录下所有文件

//输出目录下所有文件
public class Test3 {
    public static void main(String[] args) {
        showAllFiles("f:/java151/FileTest/YTR");
    }
    public static void showAllFiles(String path){
        File file = new File(path);
        if(!file.exists() || !file.isDirectory()){
            return;
        }
        File[] files = file.listFiles();
        for (File f : files){
            if(f.isDirectory()){
                System.out.println(f.getPath()+">>>");
                showAllFiles(f.getPath());
            }else {
                System.out.println(f.getPath());
            }
        }
    }
}

IO流

input输入流,程序从文件读数据。   output输出流,程序向文件写数据。

Java IO流以及File类_第3张图片

io流分类 

io流有很多种:

操作数据的不同分为:
字节流(以字节为传输单位)
字符流(以字符为传输单位)
按照数据传输方向的不同分为:
输入流
输出流
根据功能不同分为:
节点流(直接和文件进行交互)
处理流(不是直接作用在文件上)   

Java IO流以及File类_第4张图片

 Java IO流以及File类_第5张图片

 四个基本的流: 其他的流都是在这四个流的基础上进行扩展的
        字节输入流
        字节输出流 
        字符输入流
        字符输出流 

 Java IO流以及File类_第6张图片

Writer字符输出流

用于向某目标设备写入字符,它是所有字符输出流的根类,我们用FileWriter实现类。

覆盖写入

public class Charipop {
    public static void main(String[] args) throws Exception{
        //输出流
        //指定对哪个文件(路径)进行写操作
        //覆盖写入,会覆盖文件原有内容。
        Writer file = new FileWriter("F:/java151/FileTest/YTR/Text.txt");
        String s =  "不必说碧绿的菜畦,光滑的石井栏\n";
        //直接在方法里写内容
        file.write("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树\n");
         //写在字符串里然后加入
        file.write(s);
        file.flush(); //刷新流
        file.close(); //关闭流资源
    }
}

追加写入

public class Charipop {
    public static void main(String[] args) throws Exception{
        //输出流
        //指定对哪个文件(路径)进行写操作
        //追加写入
        Writer file = new FileWriter("F:/java151/FileTest/YTR/Text.txt",true);
        String s =  "不必说碧绿的菜畦,光滑的石井栏\n";
        //直接在方法里写内容
        filep.write("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树\n");
         //写在字符串里然后加入
        file.write(s);
        file.flush(); //刷新流
        file.close(); //关闭流资源

    }
}

Reader字符输入流

  用于从设备读取数据,它是所有字符输入流的根类  它的实现类有很多,我们使用FileReader实现类。

 //输入流       //指定操作的文件
        Reader r = new FileReader("F:/java151/FileTest/YTR/Text.txt");
        //一次读取一个字符,int接收的是个ASCII码值
        int str = r.read();
        //将ASCII码值转为字符
        System.out.println((char)str);
        //一次都读多个
        //定义一个字符数组
        char[] ch = new char[5];
        //将读取的字符存入数组,数组长度就是读取个数,int接收数组长度
        int str2 = r.read(ch);
        //从指定下标开始存,存入3个
        //int str2 = r.read(ch,1,3);
        //将字节数组转为字符串
        String st = new String(ch);
        //从指定的下标开始转换,转换个数为数组长度。
        //String st = new String(ch,0,str2);
        System.out.println(st);

字节流

在计算机中,无论是文本、图片、视频与音频都是以二进制形式存在的,IO流针对字节的输入输出提供了一系列的流,统称为字节流。

字节流是程序中最常用的流,根据传输方向分为:

字节输入流:InputStream

字节输出流:OutputStream

他们都是字节流的顶级父类。

字节输入流注意点:

中文一个字占3字节,中文标点也是。英文1个字母占1个字节。

比如中文有两个字,只读5字节,那最后的一个字会乱码。

字节输出流

覆盖写入

//若文件不存在会创建文件
OutputStream ops = new FileOutputStream("F:\\java151\\FileTest\\0420\\aaa\\aaa.txt");
        String val = "窗前明月光";
        //将字符串转为字节数组
        byte[] b = val.getBytes();
        //写入文件
        ops.write(b);
        ops.close();

追加写入

//若文件不存在会创建文件
OutputStream ops = new FileOutputStream("F:\\java151\\FileTest\\0420\\aaa\\aaa.txt",true);
        String val = "疑是地上霜";
        //将字符串转为字节数组
        byte[] b = val.getBytes();
        //写入文件
        ops.write(b);
        ops.close();

字符输入流

        //要操作的文件
        InputStream ips = new FileInputStream("F:/java151/FileTest/0420/aaa/aaa.txt");
        //中文一个字占3字节,所以这里一次读一个字,中文的标点也是一个占3字节
        byte[] c= new byte[3];
        //int接收数组长度。
        int a = ips.read(c);
        //将byte数组转为字符串,从下标0开始转,长度为数组长度
        String s1 = new String(c,0,a);
        System.out.println(s1);
        //读取多个,指针为空就返回-1,所以这里是读取文件全部内容
        byte[] b5 = new byte[3];
        int a1 = 0;
        while ((a1 = ips.read(b5))!=-1){
            String s2 = new String(b5,0,a1);
            System.out.println(s2);
        }

文件的拷贝

在应用程序中,IO流都是成对出现的,即输入输出一起使用,文件的拷贝就是通过输入流读取数据,然后输出流写数据。

字符流文件的拷贝字符文件,对于图片、视频登字节文件无法拷贝。

字节流既可以拷贝字符,又可以拷贝图片、视频等,但用字节拷贝字符可能乱码等问题,所以对于纯字符文件,建议使用字符流拷贝。

  字符流文件的拷贝

        //字符流复制文本
        File file = new File("F:\\java151\\FileTest\\0420");
        file.mkdir();
        File file1 = new File("F:\\java151\\FileTest\\0420\\text1.txt");
        file1.createNewFile();
        File file2 = new File("F:\\java151\\FileTest\\0420\\text2.txt");
        file2.createNewFile();
        //要复制的文件
        FileReader fileReader = new FileReader("F:\\java151\\FileTest\\0420\\text1.txt");
        //复制到
        FileWriter fileWriter = new FileWriter("F:\\java151\\FileTest\\0420\\text2.txt");
        int a =0;
        //一次读10个字符
        char[] chars = new char[10];
        while ((a = fileReader.read(chars)) != -1){
            //从下标0开始,到数组长度。
            fileWriter.write(chars,0,a);
            fileWriter.flush();
        }
        //先关读
        fileReader.close();
        //再关写
        fileWriter.close();

字节流文件拷贝

//创建输入流
        InputStream isp1 = new FileInputStream("F:/java151/FileTest/0420/aaa/aaa.txt");
        //创建输出流
        OutputStream ops1 = new FileOutputStream("F:/java151/FileTest/0420/aaa/aaa2.txt");
        byte[] barr = new byte[3];
        int n = 0;
        //将读取的ASCII码值存入字节数组,然后将数组长度给n
        while ((n = isp1.read(barr))!=-1){
            //将读取的内容写入到另一个文件
            ops1.write(barr,0,n);

        }
        //先关读
        isp1.close();
        //再关写
        ops1.close();

字节流缓冲区

字节流读写文件是一个字节一个字节的读写,读一个写一个,少量文件不影响,但文件量大的话这种频繁的操作文件,效率非常低。为了提高效率,可以定义一个字节数组作为缓冲区,在拷贝文件时,可以一次性读取多个字节数据,并保存在字节数组中,然后将字节数组一次性写入文件。

        //创建输入流
        InputStream isp1 = new FileInputStream("F:/java151/FileTest/0420/aaa/aaa.txt");
        //创建输出流
        OutputStream ops1 = new FileOutputStream("F:/java151/FileTest/0420/aaa/aaa2.txt");
        //定义一个字节数组,作为缓冲区
        byte[] barr = new byte[1024];
        //定义一个整型记住缓冲区的字节数。
        int n = 0;
        //将读取的ASCII码值存入字节数组,然后将数组长度给n,并判断是否到文件尾部。
        while ((n = isp1.read(barr))!=-1){
            //将读取的内容写入到另一个文件,从第一个字节开始,写入n个字节
            ops1.write(barr,0,n);

        }
        //先关读
        isp1.close();
        //再关写
        ops1.close();

缓存流

缓存流是在四类基础流[InputStream、OutputStream、Reader、Writer]之上 添加了一个缓存池功能.
BufferInutStream  BufferOutputStream BufferReader  BufferWriter 提高IO的效率,降低IO的次数。

缓存流要作用在基础流上,缓存流不再直接接收文件地址,而是接收基础流对象。

 Java IO流以及File类_第7张图片

 缓存流拷贝文件

关闭时先关闭读入,再刷新读入缓存,再关闭读入缓存,再刷新写入缓存,再关闭写入缓存,再刷新写入,然后关闭写入。

Java IO流以及File类_第8张图片

OutputStream out=new FileOutputStream("D:/AAA/g.txt");
          BufferedOutputStream  bos=new BufferedOutputStream(out);//缓存流要作用再基础流上
          String str="abcdefhijglmn";
          byte[] bytes = str.getBytes();
          bos.write(bytes);  //因为你写的内容 暂时放入缓存池中  并没有直接放入文件中。 所以文件中没有你的内容。
          //bos.flush();//刷新缓存池---把池子中的内容输入到文件上
            bos.close(); //关闭----先刷新缓冲池 再关闭流资源jj

字节缓存流

在IO包中提供了两个带缓冲流的字节流,BufferInutStream 、BufferOutputStream,这两个流内部都定义了一个大小为8192的字节数组,当调用缓存流的read()或write()方法时,首先将读写的数据存入定义好的字节数组,然后再写入文件。这种方式类似于方法给我们在内部定义了一个字节流缓冲区

字节缓存输出流

//创建字节流输出对象
        InputStream ip = new FileInputStream("F:/java151/FileTest/0420/test3.txt");
        //创建缓存字节流输出对象,接收字节流对象
        BufferedInputStream bps = new BufferedInputStream(ip);
        byte[] b = new byte[3];
        bps.read(b);
        String s = new String(b,0,b.length);
        System.out.println(s);
        ip.close();
        bps.close();

字节缓存输入流 

OutputStream ops = new FileOutputStream("F:/java151/FileTest/0420/test3.txt",true);
        BufferedOutputStream bops = new BufferedOutputStream(ops);
        String s1 = "tyrafhgoasdfcgnoaiuyesofcakshdfnoiagtoasdfsdfasdf";
        byte[] b1 = s1.getBytes();
        bops.write(b1);
        bops.flush();
        bops.close();

字符缓存输出流

 Reader r = new FileReader("F:/java151/FileTest/0420/test3.txt");
        BufferedReader br = new BufferedReader(r);
        char[] c = new char[1024];
        int i = br.read(c);
        String si = new String(c);
        System.out.println(si);

字符缓存输入流

Writer w = new FileWriter("F:/java151/FileTest/0420/test3.txt",true);
        BufferedWriter bw = new BufferedWriter(w);
        bw.write("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑葚;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子忽然从草间");
        bw.flush();
        bw.close();
        w.close();

使用字节缓存输入输出流拷贝文件

public class Aaa {
    public static void main(String[] args) throws IOException {
        //创建字节输入流
        InputStream is = new FileInputStream("F:/java151/FileTest/0420/aaa/js.png");
        //创建字节缓存输入流,接收字节输入流
        BufferedInputStream bis = new BufferedInputStream(is);
        //创建字节输出流
        OutputStream os = new FileOutputStream("F:/java151/FileTest/0420/aaa/js3.png");
        //创建字节缓存输出流,接收字节输出流
        BufferedOutputStream bos = new BufferedOutputStream(os);
        int len;
        while ((len = bis.read())!=-1){
            bos.write(len);
        }
        //关字节输入流
        is.close();
        //关字节缓存输入流
        bis.close();
        //关字节缓存输出流
        bos.close();
        //关字节输出流
        os.close();
    }
}

对象流--对java对象进行IO操作

为什么需要对象流
我们现在操作IO流的时候 都是将字符串读写操作 可不可以将java对象在文件中进行读写呢? 
将java对象进行读写操作 意义在于持久化信息  例如: 游戏存档。因为运行的时候所有的数据都是在运行内存中的,持久化是将运行内存的数据保存到硬盘上。

java对象所属的类必须实现序列化接口Serializable,否则会抛出异常NotSerializabileException;

序列化与反序列化

对象输出流经过oops.writeObject(xx),首先将对象按照其结构转换为一组字节,这个过程为对象序列化;

对象输入流oips.readObject(),和上面是反过来的,把字节转换为对象。这个过程为对象反序列化;

1. 序列化: 把内存中的java对象存储到磁盘[网盘]的过程。
 
2. 反序列化: 把磁盘中的内容读取到java对象内存中的过程。

//必须实现Serializable接口
public class xinxi implements Serializable {
    private  String name;
    private int id;

    public xinxi(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "xinxi{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}
public class Test {
    public static void main(String[] args) throws IOException {
        OutputStream ops = new FileOutputStream("F:/java151/FileTest/0420/xulie.txt");
        ObjectOutputStream oops = new ObjectOutputStream(ops);
        xinxi xx = new xinxi("张三",10);
        //序列化
        oops.writeObject(xx);
        oops.close();
    }
}

class Test2{
    public static void main(String[] args) throws Exception{
        InputStream ips = new FileInputStream("F:/java151/FileTest/0420/xulie.txt");
        ObjectInputStream oips = new ObjectInputStream(ips);
        //反序列化
        Object o = oips.readObject();
        System.out.println(o);
        oips.close();
    }
}

转换流

IO流分为字节流与字符流,有时他们之间需要互相转换,JDK提供了两个类可以完成此操作,InputStreamReader、OutputStreamWriter

InputStreamReader是Reader的子类,它可以将一个字节输入流转换为字符输入流,方便直接读取字符。
OutputStreamWriter是Writer的子类。它可以将一个字节输出流转换为字符输出流,方便直接写入字符。
需要注意,转换流只针对操作文本文件的字节流进行转换,如果是字节流操作的是图片等非文本,此时进行转换会造成数据丢失。
public class IpzhuanWr {
    public static void main(String[] args) throws IOException {
        //创建字节文件输入流
        InputStream is = new FileInputStream("F:/java151/FileTest/test.txt");
        //创建字节转换字符流
        InputStreamReader isr = new InputStreamReader(is);
        //创建字节文件输出流
        OutputStream ops = new FileOutputStream("F:/java151/FileTest/test9.txt",true);
        //创建字节转换字符流
        OutputStreamWriter osw = new OutputStreamWriter(ops);
        String s = "不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑葚;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子忽然从草间";
        osw.write(s);
        is.close();
        isr.close();
        osw.flush();
        ops.flush();
        osw.close();
        ops.close();
    }
}

你可能感兴趣的:(java)