File & IO【字节流,字节缓冲流讲解】File(In/out)putStream,Buffered(Out / IN)putStream

本文介绍了Java中的File类,详细讲解了File类的构造方法、绝对路径和相对路径、创建与删除功能以及判断和获取功能。接着探讨了IO流的概念,按照数据的流向和分类,重点解析了字节流的写数据和读数据操作,包括字节缓冲流的使用,以提高读写效率。
摘要由CSDN通过智能技术生成

目录

File类

File类概述和构造方法

 绝对路径和相对路径

File类创建功能 

File类删除功能

File类判断和获取功能

IO流

按照数据的流向:

按照数据分类:

字节流

字节流写数据【FileOutputStream】【write】

字节流写数据的三种方式

字节流写数据的两个小问题

字节流读数据【FileInputStream】【read】

 字节缓冲流【BufferedOutputStream】



IO流是什么?
1,可以将数据从本地文件中读取出来

2,可以将数据从内存保存到本地文件
File类是什么?
1,在读写数据时告诉虚拟机要操作的(文件/文件夹)在哪

2,对(文件/文件夹)本身进行操作。包括创建,删除等。
 


File类

File类概述和构造方法

  • File类介绍

    • 它是文件和目录(文件夹)的抽象表示【表示是一个路径

    • 文件和目录是可以通过File封装成对象的

    • 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的.将来是要通过具体的操作把这个路径的内容转换为具体存在的

  • File类的构造方法

    方法名说明
    File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
    File(String parent, String child)从父路径名字符串和子路径名字符串创建新的 File实例
    File(File parent, String child)从父抽象路径名和子路径名字符串创建新的 File实例
    private static void method3() {
            //File​(File parent, String child)      从父抽象路径名和子路径名字符串创建新的File实例
            File file1 = new File("C:\\itheima");
            String path = "a.txt";
            File file = new File(file1,path);
            System.out.println(file);//C:\itheima\a.txt
        }
    
        private static void method2() {
            //File​(String parent, String child)    从父路径名字符串和子路径名字符串创建新的File实例
            String path1 = "C:\\itheima";
            String path2 = "a.txt";
            File file = new File(path1,path2);//把两个路径拼接.
            System.out.println(file);//C:\itheima\a.txt
        }
    
        private static void method1() {
            //File​(String pathname)        通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
            String path = "C:\\itheima\\a.txt";
            File file = new File(path);
            //问题:为什么要把字符串表示形式的路径变成File对象?
            //就是为了使用File类里面的方法.
        }

 绝对路径和相对路径

  • 绝对路径

    是一个完整的路径,从盘符开始

  • 相对路径

    是一个简化的路径,相对当前项目下的路径

public class FileDemo02 {
    public static void main(String[] args) {
        // 是一个完整的路径,从盘符开始
        File file1 = new File("D:\\itheima\\a.txt");

        // 是一个简化的路径,从当前项目根目录开始
        File file2 = new File("a.txt");
        File file3 = new File("模块名\\a.txt");
    }
}


File类创建功能 

  • 方法分类

    方法名说明
    public boolean createNewFile()

    当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件

    不管有没有后缀名,只能创建文件,即使写aaa没有后缀也不能创建文件夹

    注意:所创建文件的文件夹必须存在

    public boolean mkdir()创建由此抽象路径名命名的目录【创建单级文件夹】【多级文件夹:嵌套一个又一个文件夹
    public boolean mkdirs()创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录【创建一个多级文件夹】
public class FileDemo3 {
    public static void main(String[] args) throws IOException {
        

        //public boolean createNewFile()    创建一个新的空的文件
                //注意点:
                    //1.如果文件存在,那么创建失败,返回false
                    //2.如果文件不存在,那么创建成功,返回true
                    //3.createNewFile方法不管调用者有没有后缀名,只能创建文件.
        File file1 = new File("C:\\itheima\\a.txt"); 【如果itheima文件夹不存在,创建失败】
        File file1 = new File("C:\\itheima\\aaa");// aaa理论上应该是一个文件夹,但创建出来的依旧是文件,只是此文件没有后缀名
        boolean result1 = file1.createNewFile();
        System.out.println(result1);
    



        //public boolean mkdir()            创建一个单级文件夹
                //注意点:
                    //1.只能创建单级文件夹,不能创建多级文件夹
                    //2.不管调用者有没有后缀名,只能创建单级文件夹
        //File file = new File("C:\\itheima\\aaa\\\bbb\\\ccc");//执行的话返回一个false,因为mkdir只能创建单级文件夹
        File file = new File("C:\\itheima\\aaa.txt");//即使加了后缀名,创建的依旧是文件夹,只是文件夹名字叫【aaa.txt】
        boolean result = file.mkdir();
        System.out.println(result);



        //public boolean mkdirs()           创建一个多级文件夹
                //注意点:
                    //1,可以创建单级文件夹,也可以创建多级文件夹
                    //2.不管调用者有没有后缀名,只能创建文件夹
        File file = new File("C:\\itheima\\aaa\\\bbb\\\ccc");// 创建成功,多级文件夹
        File file = new File("C:\\itheima\\aaa");    //创建单极的文件夹也可以
        File file = new File("C:\\itheima\\aaa.txt");    //创建成功,单级文件夹名叫aaa.txt
        boolean result = file.mkdirs();
        System.out.println(result);


        //疑问:
            //既然mkdirs能创建单级,也能创建多级.那么mkdir还有什么用啊? 是的,所以mkdir了解一下即可

    }

File类删除功能

  • 方法分类

    方法名说明
    public boolean delete()删除由此抽象路径名表示的文件或目录
public class FileDemo4 {
    //注意点:
        //1.不走回收站的.【直接从根源删除,不会停留在回收站】
        //2.如果删除的是文件,那么直接删除.如果删除的是文件夹,那么能删除空文件夹【不经过回收站】
        //3.如果要删除一个有内容的文件夹,只能先进入到这个文件夹,把里面的内容全部删除完毕,才能再次删除这个文件夹
    //简单来说:
        //只能删除文件和空文件夹.
    public static void main(String[] args) {
       
        File file = new File("C:\\itheima\\a.txt");【删除一个文件】
        boolean result = file.delete();
        System.out.println(result);
    

        File file = new File("C:\\itheima");
        boolean result = file.delete();
        System.out.println(result);
    }

File类判断和获取功能

  • 判断功能

    方法名说明
    public boolean isDirectory()测试此抽象路径名表示的File是否为目录
    public boolean isFile()测试此抽象路径名表示的File是否为文件
    public boolean exists()测试此抽象路径名表示的File【路径】是否存在
  • 获取功能

    方法名说明
    public String getAbsolutePath()返回此抽象路径名的绝对路径名字符串
    public String getPath()将此抽象路径名转换为路径名字符串
    public String getName()返回由此抽象路径名表示的文件或目录的名称
    public File[] listFiles()返回此抽象路径名表示的目录中的文件和目录的File对象数组

   getName方法注意点:
                    1.如果调用者是文件,那么获取的是文件名和后缀名
                    2.如果调用者是一个文件夹,那么获取的是文件夹的名字

 listFiles()方法

进入文件夹,获取这个文件夹里面所有的文件和文件夹的File对象,并把这些File对象都放在一个数组中返回.
        //包括隐藏文件和隐藏文件夹都可以获取.

 注意事项:        

1.当调用者不存在时,返回null

2.当调用者是一个文件时,返回null
3..当调用者是一个空文件夹时,返回一个长度为0的数组
4.当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
5.当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容

6.当调用者是一个需要权限才能进入的文件夹时,返回null


 


IO流

 O:输入/输出(Input/Output)【读写的过程】

input:从你硬盘到内存,简称      读数据                读,in,进去

output:从内存到硬盘,简称        写数据                写,out,出去

用内存为主体,对内存进行输入,从内存输出

按照数据的流向:

输入流:从硬盘往内存,读【input】                  【从硬盘读到内存】

输出流:从内存到硬盘,写【output】                【从内存写道硬盘】

按照数据分类:

  • 字节流【操作所有类型的文件    eg:视频音频图片等】

    • 字节输入流【从硬盘输入到内存,进行input,把数据从硬盘读入到内存read】

    • 字节输出流【从内存输出到硬盘,进行output,把数据从内存写入到硬盘write】

  • 字符流【只能操作纯文本文件    eg:java文件,txt文件等】

    • 字符输入流

    • 字符输出流

一般来说,我们说IO流的分类是按照数据类型来分的 


什么是纯文本文件?
用windows记事本打开能读的懂,那么这样的文件就是纯文本文件。


如果不确定文件类型,优先使用字节流。字节流是万能的流  。


字节流

字节流抽象基类

  • InputStream:这个抽象类是表示字节输入流的所有类的超类

  • OutputStream:这个抽象类是表示字节输出流的所有类的超类

  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

字节流写数据

  • 字节输出流

    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件

  • 使用字节输出流写数据的步骤

    • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)

    • 调用字节输出流对象的写数据方法

    • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)

 构造方法:

FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
参数:写入数据的目的
    String name:目的地是一个文件的路径
    File file:目的地是一个文件
构造方法的作用:
    1.创建一个FileOutputStream对象
    2.会根据构造方法中传递的文件/文件路径,创建一个空的文件
    3.会把FileOutputStream对象指向创建好的文件
public class OutputDemo2 {
    public static void main(String[] args) throws IOException {
        //1.创建字节输出流的对象
                        //注意点:如果文件不存在,会帮我们自动创建出来.
                        //       如果文件存在,会把文件原本内容清空在写入.
        FileOutputStream fos = new FileOutputStream("C:\\itheima\\a.txt");

        //2,写数据     传递一个整数时,那么实际上写到文件中的,是这个整数在码表中对应的那个字符.
        fos.write(98);
        fos.write(99);
        fos.write(100);
        //3,释放资源
        fos.close(); //告诉操作系统,我现在已经不要再用这个文件了.已经结束了写入数据操作

    }
}
执行结果:文件内显示abc

字节流写数据的三种方式

写数据的方法分类

方法名说明
void write(int b) 一次写一个字节数据   写到文件中
void write(byte[] b) 一次写一个字节数组数据
void write(byte[] b, int off, int len)一次写一个字节数组的部分数据,从off索引开始,写入len个
public class OutputDemo4 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");

        /*byte [] bys = {97,98,99};
        fos.write(bys);*/

        byte [] bys = {97,98,99,100,101,102,103};
        fos.write(bys,1,2);

        fos.close();
    }
}
执行结果:a文件里面存放bc

字节流写数据的两个小问题

  • 字节流写数据如何实现换行

    • windows:\r\n

    • linux:\n

    • mac:\r

  • 字节流写数据如何实现追加写入【如果原本存在文件,每次写入数据都会清空之前存在的数据,如果想在原本内容下继续写,则利用追加写操作】

    • 构造方法

    • public FileOutputStream(String name,boolean append)

    • public FileOutputStream(File file,boolean append)

    • 如果第二个参数为true ,则字节将写入文件的末尾而不是开头

public class OutputDemo5 {
    public static void main(String[] args) throws IOException {
        //第二个参数就是续写开关,如果没有传递,默认就是false,
        //表示不打开续写功能,那么创建对象的这行代码会清空文件.

        //如果第二个参数为true,表示打开续写功能
        //那么创建对象的这行代码不会清空文件.
        FileOutputStream fos = new FileOutputStream("bytestream\\a.txt",true);
        
        //fos.write("\r\n");【直接写\r\n成了字符串,不是字节无法添加到文件当中,
利用字符串里的getBytes方法,将字符串存入字节数组中】
       

         fos.write(97);
        //能加一个换行
        fos.write("\r\n".getBytes());
        fos.write(98);
        //能加一个换行
        fos.write("\r\n".getBytes());
        fos.write(99);
        //能加一个换行
        fos.write("\r\n".getBytes());
        fos.write(100);
        //能加一个换行
        fos.write("\r\n".getBytes());
        fos.write(101);
        //能加一个换行
        fos.write("\r\n".getBytes());

        fos.close();
    }
}
执行结果:a文件里显示
a
b
c
d
e
public class OutputDemo6 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            //System.out.println(2/0);
            fos = new FileOutputStream("D:\\a.txt");
            fos.write(97);
        }catch(IOException e){
           e.printStackTrace();
        }finally {
            //finally语句里面的代码,一定会被执行.
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}


字节流读数据

  • 字节输入流

    • 构造方法

    • FileInputStream(String name) 
      FileInputStream(File file)
      参数:读取文件的数据源
          String name:文件的路径
          File file:文件
      构造方法的作用:
          1.会创建一个FileInputStream对象
          2.会把FileInputStream对象指定构造方法中要读取的文件
  • 字节输入流读取数据的步骤

    • 创建字节输入流对象

    • 调用字节输入流对象的读数据方法

    • 释放资源

 成员方法

int read()从输入流中读取数据的下一个字节。   当后续没内容是,返回-1
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。返回值为读取的有效个数
void close() 关闭此输入流并释放与该流关联的所有系统资源。

(一次读一个字节数据) 

public class OutputDemo7 {
    public static void main(String[] args) throws IOException {
        //如果文件存在,那么就不会报错.
        //如果文件不存在,那么就直接报错.
        FileInputStream fis = new FileInputStream("bytestream\\a.txt");

【假如文件中只有一个a字母】
        int read = fis.read();
        //一次读取一个字节,返回值就是本次读到的那个字节数据.
        //返回的值也就是字符在码表中对应的那个数字.
        //如果我们想要看到的是字符数据,那么一定要强转成char

        //System.out.println(read);【如果文件里存的是a,则输出的是97数字】
        System.out.println((char)read);

        //释放资源
        fis.close();
    }
}

 一次读取多个字节

public class OutputDemo8 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("bytestream\\a.txt");
        //1,文件中多个字节我怎么办?
        /*while(true){
            int i1 = fis.read();
            System.out.println(i1);
        }*/

        int b;
        while ((b = fis.read())!=-1){
            System.out.println((char) b);
        }
        fis.close();
    }
}

案例: 复制文件

public class OutputDemo9 {
    public static void main(String[] args) throws IOException {
        //创建了字节输入流,准备读数据.
        FileInputStream fis = new FileInputStream("C:\\itheima\\a.avi");
        //创建了字节输出流,准备写数据.
        FileOutputStream fos = new FileOutputStream("bytestream\\a.avi");

        int b;
        while((b = fis.read())!=-1){
            fos.write(b);
        }

        fis.close();
        fos.close();
    }
}

 思考:如果复制一个超级大文件,采用之前的方法,挨个读,挨个写太慢了。有什么更好的办法

public class OutputDemo10 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\itheima\\a.avi");
        FileOutputStream fos = new FileOutputStream("bytestream\\a.avi");

        byte [] bytes = new byte[1024];【相当于一个买鸡蛋的篮子,通过篮子批量往里装进行输送】
        int len;//本次读到的有效字节个数 --- 这次读了几个字节

        while((len = fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }

        fis.close();
        fos.close();
    }
}

创建个自己数组(容器),使用read一次读取文件中1024个坑位,返回值为有多少个坑位中真正有内容。如果全都没内容,就返回-1 


 字节缓冲流

另一种方式:提高读和写的效率

BufferedOutputStream        字节缓冲输出流

BufferedInputStream           字节缓冲输入流

  • 字节缓冲流介绍

    • lBufferOutputStream:该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用

    • lBufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节

  • 构造方法:

    方法名说明
    BufferedOutputStream(OutputStream out)创建字节缓冲输出流对象
    BufferedInputStream(InputStream in)创建字节缓冲输入流对象

为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作

读写方法的底层依旧是调用字节流的读写方法
 【提供一个储备仓库,提前放入资源】

public class OutputDemo11 {【利用缓冲流一个字节一个字节的拷贝】
    public static void main(String[] args) throws IOException {
        //就要利用缓冲流去拷贝文件

        //创建一个字节缓冲输入流
        //在底层创建了一个默认长度为8192的字节数组。
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));
        //创建一个字节缓冲输出流
        //在底层也创建了一个默认长度为8192的字节数组。
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));

        int b;
        while((b = bis.read()) != -1){
            bos.write(b);
        }

        //方法的底层会把字节流给关闭。
        bis.close();
        bos.close();

    }
}

创建了一个长度为8192的字节数组。

倒手的过程是在内存中进行的,内存的数度很快


package com.itheima.output;

import java.io.*;

public class OutputDemo12 {
    public static void main(String[] args) throws IOException {
        //缓冲流结合数组,进行文件拷贝

        //创建一个字节缓冲输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));

【参数传递是字节流,来指定文件路径位置,真正干活的是字节流,而缓冲流只是提供了一个提高效率的功能】

        //创建一个字节缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));

        byte [] bytes = new byte[1024];
        int len;
        while((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }

        bis.close();
        bos.close();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值