【Day08-IO-文件&字节流】

File

        1. 概述

        File对象既可以代表文件、也可以代表文件夹。它封装的对象仅仅是一个路径名,这个路径可以存在,也可以不存在

构造器

说明

public File​(String pathname)

根据文件路径创建文件对象

public File​(String parent, String child)

根据父路径和子路径名字创建文件对象

public File​(File  parent, String child)

根据父路径对应文件对象和子路径名字创建文件对象

        1、File类构建对象的方式是什么样的?File的对象可以代表哪些东西?

                File file = new File(“文件/文件夹/绝对路径/相对路径”);

        2、绝对路径和相对路径是什么意思?

                绝对路径是带盘符的。

                相对路径是不带盘符的,默认到当前工程下寻找文件。

        2. File提供的判断文件类型、获取文件信息功能

方法名称

说明

public boolean exists()

判断当前文件对象,对应的文件路径是否存在,存在返回true

public boolean isFile()

判断当前文件对象指代的是否是文件,是文件返回true,反之。

public boolean isDirectory()

判断当前文件对象指代的是否是文件夹,是文件夹返回true,反之。

public String getName()

获取文件的名称(包含后缀)

public long length()

获取文件的大小,返回字节个数

public long lastModified()

获取文件的最后修改时间。

public String getPath()

获取创建文件对象时,使用的路径

public String getAbsolutePath()

获取绝对路径

/*
常用方法1:判断文件类型、获取文件信息
    boolean exists() 判断文件路径是否存在
    boolean isFile() 判断是否是文件(不存在的都是false)
    boolean isDirectory() 判断是否是文件夹(不存在的都是false)
    String getName() 获取文件/文件名,包含后缀
    long length() 获取文件大小,返回字节个数
    long lastModified() 获取最后修改时间
    string getPath() 获取创建对象时的路径
    String getAbsolutePath() 获取对象绝对路名
*/
public class Demo2 {
    public static void main(String[] args) {
        File f1 = new File("day08-code/test1");//文件夹-已存在
        File f2 = new File("day08-code/test1/1.txt");//文件-已存在

        File f3 = new File("day08-code/test2");//文件夹-不存在
        File f4 = new File("day08-code/test2/2.txt");//文件-不存在

        //boolean exists() 判断文件路径是否存在
        System.out.println(f1.exists());//true
        System.out.println(f3.exists());//false
        //boolean isFile() 判断是否是文件
        System.out.println(f2.isFile());//true
        System.out.println(f4.isFile());//false
        //boolean isDirectory() 判断是否是文件夹
        System.out.println(f1.isDirectory());//true
        System.out.println(f2.isDirectory());//false
        //String getName() 获取文件/文件名,包含后缀
        System.out.println(f2.getName());//1.txt
        //long length() 获取文件大小,返回字节个数
        System.out.println(f2.length());//0
        //long lastModified() 获取最后修改时间
        System.out.println(f2.lastModified());//1697894961950
        //string getPath() 获取创建对象时的路径
        System.out.println(f2.getPath());//day08-code\test1\1.txt
        //String getAbsolutePath() 获取对象绝对路径
        System.out.println(f2.getAbsolutePath());//D:\ITheima\code\SE-advance\day08-code\test1\1.txt
    }
}

        3. File类创建和删除文件的功能

方法名称

说明

public boolean mkdir()

只能创建一级文件夹

public boolean mkdirs()

可以创建多级文件夹

public boolean createNewFile()

创建一个新的空的文件

方法名称

说明

public boolean delete​()

删除文件、空文件夹

注意:delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站

/*
File创建和删除方法
    boolean mkdir()   创建单级文件夹,创建失败返回false
    boolean mkdirs()   创建多级文件夹 (常用)

    boolean createNewFile()  创建文件,文件存在返回false

    boolean delete()  删除文件或空文件夹,删除失败返回false (注意: 删除方法不走回收站,填用)
*/
public class Demo3 {
    public static void main(String[] args) throws IOException {
        File f1 = new File("day08-code/test2");
        File f2 = new File("day08-code/test2/test3");
        File f3 = new File("day08-code/test2/2.txt");
        File f4 = new File("day08-code/test2/2");

        //boolean mkdir()   创建单级文件夹,创建失败返回false
//        System.out.println(f1.mkdir());//true ,已存在再次创建会失败
        //boolean mkdirs()   创建多级文件夹 (常用)
//        System.out.println(f2.mkdirs());//true
        //boolean createNewFile()  创建文件,文件存在返回false
//        System.out.println(f3.createNewFile());//true
//        System.out.println(f4.createNewFile());//true 空白格式
        //boolean delete()  删除文件或空文件夹,删除失败返回false (注意: 删除方法不走回收站,填用)
//        System.out.println(f2.delete());//true 删除多级文件会失败
    }
}

         4.File类提供的遍历文件夹的功能

方法名称

说明

public String[] list()

获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。

public File[] listFiles()

获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)

         使用listFiles方法时的注意事项

  • 当主调是文件,或者路径不存在时,返回null
  • 当主调是空文件夹时,返回一个长度为0的数组
  • 当主调是一个非空文件夹,但是没有权限访问该文件夹时,返回null
/*
查看目录中的内容
    String[] list()	获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
    File[] listFiles()	获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回,包含隐藏文件(重点)

注意事项
    当主调是文件,或者路径不存在时,返回null
    当主调是空文件夹时,返回一个长度为0的数组
    当主调是一个非空文件夹,但是没有权限访问该文件夹时,返回null
*/
public class Demo4 {
    public static void main(String[] args) {
        File file = new File("D:\\code\\SE-advance\\day08-code");
        //String[] list()  返回文件名数组
        String[] names = file.list();
        for (String name : names) {
            System.out.println(name);
        }
        //File[] listFiles() 返回文件数组
        File[] files = file.listFiles();
        for (File file1 : files) {
            System.out.print(file1);
            if (file1.isFile()) {
                System.out.println("--是文件");
            } else {
                System.out.println("--是文件夹");
            }
        }
    }
}

        5. 案例:

/*
需求:
    从D:盘中,搜索“QQ.exe” 这个文件,找到后直接输出其位置。
分析:
    先找出D:盘下的所有一级文件对象
    遍历全部一级文件对象,判断是否是文件
    如果是文件,判断是否是自己想要的
    如果是文件夹,需要继续进入到该文件夹,重复上述过程
*/
public class Demo5 {
    public static void main(String[] args) {
        File parent = new File("D:\\");
        findFile(parent, "QQ.exe");
    }

    public static void findFile(File parent, String filename) {
        //获取当前目录所有文件夹
        File[] files = parent.listFiles();
        //判断当前文件是否为空,或不存在
        if (files == null || files.length == 0) {
            return;
        }
        //循环遍历所有文件、文件夹
        for (File file : files) {
            //判断当前file是否是文件
            if (file.isFile()) {
                if (file.getName().equals(filename)) {
                    //如果是文件:判断文件的名称和查找的文件是否一致
                    System.out.println(file.getAbsolutePath());
                }
            } else {
                //如果不是文件,进入文件夹继续查找
                findFile(file, filename);
            }
        }
    }
}

字符集

        1. 标准ASCII字符集

        ASCII(American Standard Code for Information Interchange): 美国信息交换标准代码,包括了英文、符号等。

        标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符,对美国佬来说完全够用。

        GBK(汉字内码扩展规范,国标)

  • 汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储
  • 注意:GBK兼容了ASCII字符集。

1、常见字符集有哪些?各自存储数据的特点是什么?

        ASCII字符集: 只有英文、数字、符号等,占1个字节。

        GBK字符集:   汉字占2个字节,英文、数字占1个字节。

        UTF-8字符集:汉字占3个字节,英文、数字占1个字节。

        2. 字符集的编码、解码操作 

        Java代码完成对字符的编码

String提供了如下方法

说明

byte[] getBytes​()

使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中

byte[] getBytes​(String charsetName)

使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

        Java代码完成对字符的解码

String提供了如下方法

说明

String​(byte[] bytes)

通过使用平台的默认字符集解码指定的字节数组来构造新的String

String​(byte[] bytes, String charsetName)

通过指定的字符集解码指定的字节数组来构造新的String

注意字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码

/*
编码: 字符-->字节
    byte[] getBytes()	使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
    byte[] getBytes(String charsetName)	使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

解码: 字节-->字符
    String(byte[] bytes)	通过使用平台的默认字符集解码指定的字节数组来构造新的String
    String(byte[] bytes, String charsetName)	通过指定的字符集解码指定的字节数组来构造新的String
*/
public class Demo2 {

    public static void main(String[] args) throws UnsupportedEncodingException {
        //编码: 字符-->字节
        String str = "你爱wo";
//        byte[] bytes = str.getBytes();//8 默认是计算机自己的字符串集
        byte[] bytes = str.getBytes("GBK");//6
        System.out.println(bytes.length);

        //解码: 字节-->字符
//        String s = new String(bytes);//�㰮wo 默认也是计算机上的
        String s = new String(bytes, "GBK");//你爱wo
        System.out.println(s);
    }
}

1、如何使用Java程序对字符进行编码?

String类下的方法:

byte[] getBytes​()使用默认字符集编码

byte[] getBytes​(String charsetName)使用指定字符集编码

2、如何使用Java程序对字节进行解码?

String类的构造器:

String​(byte[] bytes):使用默认字符集解码

String​(byte[] bytes, String charsetName))使用指定字符集解码

IO

        1. IO流的分类

IO总体来看就有四大流

字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流

字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流。

字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。

字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。

        1、IO流的作用?

读写文件数据的

        2、IO流是怎么划分的,大体分为几类,各自的作用?

字节输入流 InputStream(读字节数据的)

字节输出流 OutoutStream(写字节数据出去的)

字符输入流 Reader(读字符数据的)

字符输出流 Writer(写字符数据出去的)

        2. IO流-字节流

        文件字节输入流:每次读取一个字节

 

        2.1 FileInputStream(文件字节输入流)

        作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中来。

构造器

说明

public FileInputStream​(File file)

创建字节输入流管道与源文件接通

public FileInputStream​(String pathname)

创建字节输入流管道与源文件接通

方法名称

说明

public int read()

每次读取一个字节返回,如果发现没有数据可读会返回-1.

public int read(byte[] buffer)

每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

注意: 使用FileInputStream每次读取一个字节,读取性能差,并且读取汉字输出会乱码 

/*
文件字节输入流
    作用:
        读取文件中的内容到程序中,结果是字节
    语法:
        FileInputStream(File file)	        创建字节输入流管道与源文件接通
        FileInputStream(String pathname)	创建字节输入流管道与源文件接通
    方法(1次读1个字节)
        int read()	每次读取一个字节返回, 如果发现没有数据可读会返回-1
*/
public class Demo1 {
    public static void main(String[] args) throws IOException {
        //1. 创建文件字节输入流(c_demo1.txt)
//        File file = new File("day08-code/c_demo1.txt");
//        FileInputStream fis = new FileInputStream(file);
        FileInputStream file = new FileInputStream("day08-code/c_demo1.txt");

        //2. 读取文件中的内容
        //2.1 定义一个文件读取的变量
        int read;
        //2.2 while中 读取一次,赋值到变量,判断是否 != -1
        while ((read = file.read()) != -1) {
            System.out.println(read);
        }

        //3. 如果流操作完毕, 应该主动关闭流
        file.close();
    }
}

        1、文件字节输入流的作用是什么?

                从磁盘中读取内容到程序中

        2、每次读取一个字节的方法是哪个?

                public int read()

        3、每次读取一个字节存在什么问题?

                读取性能较差,并且读取汉字输出会乱码。

        2.2 FileInputStream(文件字节输入流)

  • 作用:以内存为基准,把文件中的数据以字节的形式读入到内存中来。 

    方法名称

    说明

    public int read()

    每次读取一个字节返回,如果发现没有数据可读会返回-1.

    public int read(byte[] buffer)

    每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

注意: 使用FileInputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码。

/*
文件字节输入流(1次读多个字节)
    int read(byte[] buffer)	每次用一个字节数组去读取数据, 返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.
*/
public class Demo2 {
    public static void main(String[] args) throws IOException {
        //1. 创建文件字节输入流(c_demo2.txt)
        FileInputStream file = new FileInputStream("day08-code/c_demo2.txt");
        //2. 读取文件中的内容
        byte[] bytes = new byte[3];
        //使用while循环遍历
        //定义一个读取的长度,默认为空
        int len;
        //在while中,读取一次赋值到长度变量,判断是不是-1
        while ((len = file.read(bytes)) != -1) {
            String str = new String(bytes, 0, len);
            System.out.println("读取了" + len + "个字节,内容是:" + str);
        }
        //3. 如果流操作完毕, 应该主动关闭流
        file.close();
    }
}

        1、文件字节输入流,每次读取一个字节数组的方法是哪个?

方法名称

说明

public int read(byte[] buffer)

每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

        2、每次读取一个字节数组有什么好处? 存在什么问题?

                读取的性能得到了提升

                读取中文字符输出无法避免乱码问题

        2.3 文件字节输入流:一次读取完全部字节 

         方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。

方法名称

说明

public int read(byte[] buffer)

每次用一个字节数组去读取,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

         方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。

方法名称

说明

public byte[] readAllBytes()

直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回

/*
文件字节输入流(1次读所有字节)

    方式1:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
        public int read(byte[] buffer)	每次用一个字节数组去读取,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

    方式2: Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。
        public byte[] readAllBytes()   直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回

*/
public class Demo3 {
    public static void main(String[] args) throws IOException {
        //1. 创建文件字节输入流(c_demo3.txt)
        File file = new File("day08-code/c_demo3.txt");
        FileInputStream fis = new FileInputStream(file);

        //2. 读取文件中的内容
        //方式1: 定义一个跟文件同样大小的数组,一次接收所有
//        byte[] bytes = new byte[(int) file.length()];
//        int len = fis.read(bytes);
//        System.out.println(new String(bytes,0 ,len));//abcdefgh我都快学吐了,但是想想心愿墙上立下的目标,我决定:抽根烟,继续搞!!!
        //方式2: 直接使用readAllBytes将文件中所有内容读取到数组
        byte[] bytes = fis.readAllBytes();
        System.out.println(new String(bytes));//abcdefgh我都快学吐了,但是想想心愿墙上立下的目标,我决定:抽根烟,继续搞!!!
        //3. 如果流操作完毕, 应该主动关闭流
        fis.close();
    }
}

        1、如何使用字节输入流读取中文内容输出时不乱码呢?

                一次性读取完全部字节

                可以定义与文件一样大的字节数组读取,也可以使用官方API

        2、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?

                如果文件过大,定义的字节数组可能引起内存溢出。

文件字节输出流:写字节出去

         2.4 FileOutputStream(文件字节输出流)

作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。

构造器

说明

public FileOutputStream​(File file)

创建字节输流管道与源文件对象接通

public FileOutputStream​(String filepath)

创建字节输流管道与源文件路径接通

public FileOutputStream​(File fileboolean append)

创建字节输流管道与源文件对象接通,可追加数据

public FileOutputStream​(String filepathboolean append)

创建字节输流管道与源文件路径接通,可追加数据

/*
文件字节输出流
    作用:
        向文件中写入字节内容
    语法:
        FileOutputStream(String filepath)	创建字节输出流管道与源文件路径接通
        FileOutputStream(String filepath, boolean append)	创建字节输出流管道与源文件路径接通,可追加数据
    方法
        void write(int a)	写一个字节出去
        void write(byte[] buffer)	写一个字节数组出去
        void write(byte[] buffer, int pos, int len)  写一个字节数组的一部分出去
        void close()  关闭流
    注意:
        如果要写出换行, 需要写"\r\n"的字节数组表示形式
*/
public class Demo4 {
    public static void main(String[] args) throws IOException {
        //创建文件字节输出流(c_demo4.txt)
        FileOutputStream file = new FileOutputStream("day08-code/c_demo4.txt");
        file.write(98);
        file.write("\r\n".getBytes());
        String str = "我A你";
        file.write(str.getBytes());
        file.write("\r\n".getBytes());

        byte[] bytes = {99, 98, 97, 100, 102};
        file.write(bytes);

        //关闭流
        file.close();
    }
}

        1、如何创建文件字节输出流,如何实现写数据的追加操作?

                public FileOutputStream​(String filepathboolean append)

        2、字节输出流写数据的方法有哪些?

public void write(int a)

public void write(byte[] buffer)

public void write(byte[] buffer , int pos , int len)

        3、字节输出流如何实现写出去的数据可以换行?

                写"\r\n"的字节数组表示形式

 案例:

/*
文件复制
    源文件-->输入流-->程序-->输出流-->目标文件

步骤:
    1. 创建文件的输入流,对应到源文件; 创建文件输出流,对应到目标文件
    2. 使用输入流读取数据,使用输出流写出数据(边读边写)
    3. 释放资源(关闭流)
*/
public class Demo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\ITheima\\zm.png");
        FileOutputStream fos = new FileOutputStream("E:\\PersonalData\\University\\picture.png");
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes,0,len);
        }
        fos.close();
        fis.close();
    }
}
  • 41
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值