【Java八股文之基础篇(七)】IO流的面试高频问题

本文详细介绍了Java中的IO流概念及应用,包括File类的基本操作、字节输入输出流的使用方法,以及如何进行文件和文件夹的复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO流

File

概述

File对象主要是用来表示文件或者是目录的路径的。类中提供了很多对文件或者文件夹操作的常用方法。

创建对象

  • 绝对路径
    以磁盘名开头的路径。例如:D:\Program Files\Java\jdk1.8.0_172

  • 相对路径
    不是以盘符开头的,相对于当前项目下的路径。例如: a.txt

File(String pathname) //通过字符串类型的路径来创建对象
File(String parent, String child) //通过父目录的路径(字符串类型)和文件(文件夹)名称来创建对象
File(File parent, String child)//通过父目录的路径(File类型)和文件(文件夹)名称来创建对象

常用方法

方法含义
boolean createNewFile()根据路径创建一个文件,返回值代表创建是否成功
boolean mkdir()根据路径创建一个文件夹,返回值代表创建是否成功
boolean mkdirs()根据路径创建一个文件夹,如果父目录不存在会自动创建父目录
boolean exists()判断文件或者文件夹是否存在
boolean isFile()判断是否是一个文件
boolean isDirectory()判断是否是一个文件夹
boolean delete()删除文件,或者删除空文件夹,返回值代表删除是否成功
long length()获取一个文件的大小,对文件夹无意义
String getName()获取文件或文件夹的名字
File getParentFile()获取父目录的File对象
String getAbsolutePath()获取File对象的绝对路径

重要方法

方法含义
File[] listFiles()如果当前File对象是一个文件夹,可以获取文件夹下的所有文件或者文件夹的File对象。
 public static void main(String[] args) {
        File dir = new File("C:\\Users\\root\\Desktop\\test\\a.txt");
        File[] files = dir.listFiles();
        if(files!=null){
            for (File file : files) {
                System.out.println(file);
            }
        }
    }

注意:如果不是文件夹或者是文件夹的权限受限返回值是null。所以一定要对返回结果做非空判断。

IO流

概述

当需要进行数据的传输的时候可以使用IO流来进行。例如:把磁盘中文件的数据读取到内存中。把内存中的数据写入到磁盘中。把网络中的数据读取到内存中(Socket编程)

分类

IO流根据处理数据类型的不同分为字符流字节流,根据数据流向不同分为输入流输出流对输入流只能进行读操作,对输出流只能进行写操作

数据类型流向顶层父类
字节流输入(读)java.io.InputStream
字节流输出(写)java.io.OutputStream
字符流输入(读)java.io.Reader
字符流输出(写)java.io.Writer

字节输入流

所有字节输入流的父类是 java.io.InputStream ,它是以字节为单位的输入流 。我们就以FileInputStream为例进行学习。

FileInputStream概述

FileInputStream是用来读取文件数据的字节输入流。

对象的创建

构造方法如下:

FileInputStream(String name) throws FileNotFoundException  //传入文件路径创建对象
FileInputStream(File file) throws FileNotFoundException    //传入文件路径的File对象来创建流对象    

范例:

 public static void main(String[] args) throws FileNotFoundException {
        //创建对象
        FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
        System.out.println(fis);

        File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
        FileInputStream fis2 = new FileInputStream(file);
        System.out.println(fis2);
    }
读取数据

我们可以使用FileInputStream来读取文件中的字节数据。

一次读一个字节

核心方法

public int read() throws IOException // 读取一个字节的数据作为返回值返回  返回值为-1时代表以及没有内容了

范例

//如果用这个输入流去读一个字符串,输出都是数字,可以理解为字符串在磁盘里是以二进制存储,然后这个流
//每次读一个字节,也就读8个0或1,返回了int值,所以返回的值是0-255.
public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
        //读取数据
        int b;
        while((b=fis.read())!=-1){
            System.out.println(b);
        }
        //释放资源
        fis.close();
    }
一次读取一个字节数组

核心方法如下:

public int read(byte b[]) throws IOException //传入一个字节数组,最多读取一个字节数组的数据,并且会把数据存入数组中,返回值代表本次读取到的字节的个数。   如果返回值为-1代表没有数据了

范例

 public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
        //读取数据  一次读一个字节数组
        byte[] bytes = new byte[1024*2];
        int len;
        while ((len=fis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
        //释放资源
        fis.close();
    }
资源释放

我们在前面处理异常的时候都同意做了声明抛出的处理。但是这很可能导致在出现了异常时资源没有被正确的释放。所以我们要更合理的处理异常,尤其是处理资源释放的问题。

jdk6版本
 private static void test() {
        FileInputStream fis = null;
        try{
            fis = new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
            //读取数据  一次读一个字节数组
            byte[] bytes = new byte[1024*2];
            int len;
            while ((len=fis.read(bytes))!=-1){
                System.out.println(new String(bytes,0,len));
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //释放资源
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
jdk7版本

可以使用try…catch…resource的写法,在try的后面可以加小括号,把需要释放的资源在小括号中定义。我们就不需要自己去释放资源,jvm会帮我们再最后调用close方法释放资源的。

private static void test2() {
        try(FileInputStream fis =new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt"); ){
            //读取数据  一次读一个字节数组
            byte[] bytes = new byte[1024*2];
            int len;
            while ((len=fis.read(bytes))!=-1){
                System.out.println(new String(bytes,0,len));
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
jdk9版本

资源的定义也可以不放在try的小括号中,只要在try的小括号中声明要释放的资源即可。

 private static void test3() throws FileNotFoundException {
        FileInputStream fis =new FileInputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
        try(fis ){
            //读取数据  一次读一个字节数组
            byte[] bytes = new byte[1024*2];
            int len;
            while ((len=fis.read(bytes))!=-1){
                System.out.println(new String(bytes,0,len));
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

字节输出流

所有字节输出流的父类是 java.io.OutputStream ,它是以字节为单位的输出流 。我们就以FileOutputStream为例进行学习。

FileOutputStream概述

FileOutputStream是用来往文件中写入数据的字节输出流。

对象的创建

构造方法如下

FileOutputStream(String name) throws FileNotFoundException //传入文件路径创建对象
FileOutputStream(File file) throws FileNotFoundException    //传入文件路径的File对象来创建流对象

示例

 public static void main(String[] args) throws FileNotFoundException {
        FileOutputStream fos = new FileOutputStream("C:\\Users\\root\\Desktop\\test\\11.txt");
        File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
        FileOutputStream fos2 = new FileOutputStream(file);
    }
写数据

我们可以使用FileOutputStream来往文件中写入字节数据。

一次写一个字节

核心方法:

public void write(int b) throws IOException //传入一个字节数据,把字节数据写入文件
//这里测试过,并非真的传入一个int值,而是传入大小为一个字节的数据,比如‘a’

范例:

 public static void main(String[] args) throws IOException {

        File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
        FileOutputStream fos = new FileOutputStream(file);

        fos.write('a');//写出去的结果就是字符a

        fos.close();
    }
一次写一个字节数组

核心方法如下:

public void write(byte b[]) throws IOException     //  存入一个字节数组,把字节数组中的数据全部写入文件
public void write(byte b[], int off, int len) throws IOException  //存入一个字节数组,把字节数组中从off索引开始len个元素写入文件

范例:

 public static void main(String[] args) throws IOException {

        File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
        FileOutputStream fos = new FileOutputStream(file);


        byte[] bytes = "abc".getBytes();
//        fos.write(bytes);
        fos.write(bytes,0,2);

        fos.close();
    }
文件续写

如果用之前的构造方法创建的流对象,每次流对象创建的时候就会把文件中的内容清空。所以没有办法实现续写的效果。如果需要续写就需要使用另外的构造方法。

FileOutputStream(String name, boolean append) throws FileNotFoundException //第二个参数代表是否续写
FileOutputStream(File file, boolean append) throws FileNotFoundException  //第二个参数代表是否续写

当append值为true时候,就说明要续写。
范例:

 public static void main(String[] args) throws IOException {

        File file = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
        FileOutputStream fos = new FileOutputStream(file,true);


        byte[] bytes = "abc".getBytes();
//        fos.write(bytes);
        fos.write(bytes,0,2);

        fos.close();
    }

练习

文件复制
要求定义一个方法,该方法能够实现文件的复制
public static void main(String[] args) throws IOException {
//        要求定义一个方法,该方法能够实现文件的复制
        // 文件的复制就是循环的读写,直到操作完所有数据为止
        File src = new File("C:\\Users\\root\\Desktop\\test\\11.txt");
        File destDir = new File("C:\\Users\\root\\Desktop\\test\\a");
        copyFile(src,destDir);
    }

    //源文件的路径  File srcFile
    //目标文件的存放目录路径  File destDir
    public static void copyFile(File srcFile,File destDir) throws IOException {
        //在destDir下创建一个和srcFile同名的文件
        File destFile = new File(destDir,srcFile.getName());
        //读取源文件  把读到的数据写入目标文件destFile
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        byte[] bytes = new byte[1024];
        int len;
        while((len=fis.read(bytes))!=-1){
            //把读到的内容写入新文件中
            fos.write(bytes,0,len);
        }
        //释放资源
        fis.close();
        fos.close();

    }
文件夹复制
要求定义一个方法,该方法能够实现文件夹的复制,考虑有子文件夹的情况
public class Test09 {
    public static void main(String[] args) throws IOException {
        //要求定义一个方法,该方法能够实现文件夹的复制,考虑有子文件夹的情况
        File srcDir = new File("C:\\Users\\root\\Desktop\\test");
        File dest = new File("C:\\Users\\root\\Desktop\\test2");
        copyDir(srcDir,dest);
    }

    //File srcDir  源文件夹
    //File dest要复制到哪个目录
    public static void copyDir(File srcDir,File dest ) throws IOException {
        if(!(srcDir.exists()&&srcDir.isDirectory())){
            throw new RuntimeException("源文件夹必须存在并且是一个文件夹");
        }
        if(!dest.isDirectory()){
            throw new RuntimeException("目标文件夹必须是一个文件夹");
        }
        //1.在目标文件夹下创建一个和源文件夹同名的文件夹destDir
        File destDir = new File(dest,srcDir.getName());
        destDir.mkdirs();
        //2.获取源文件夹下的所有子文件
        File[] files = srcDir.listFiles();
        if(files!=null){
            //3.遍历数组,复制每一个文件到目标文件夹destDir下
            for (File file : files) {
                if(file.isFile()){
                    copyFile(file,destDir);
                }else {
                    //复制文件夹
                    copyDir(file,destDir);
                }

            }
        }

    }


    //源文件的路径  File srcFile
    //目标文件的存放目录路径  File destDir
    public static void copyFile(File srcFile,File destDir) throws IOException {
        //在destDir下创建一个和srcFile同名的文件
        File destFile = new File(destDir,srcFile.getName());
        //读取源文件  把读到的数据写入目标文件destFile
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        byte[] bytes = new byte[1024];
        int len;
        while((len=fis.read(bytes))!=-1){
            //把读到的内容写入新文件中
            fos.write(bytes,0,len);
        }
        //释放资源
        fis.close();
        fos.close();

    }
}

以上就是字节流的相关知识点,下篇讲解字符流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kplusone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值