Java文件的读写

本文介绍了Java中对文件进行读写的常见操作,包括File类的使用,以及FileInputStream、BufferedInputStream、FileOutputStream和BufferedOutputStream等字节流和缓存流的详细应用。通过示例展示了如何高效地读取和写入文件,并强调了缓存流提高代码效率的重要性。

文件与流

在实际生活中,我们总要对文件进行操作,Java提供了流可以帮助我们读写文件;
下面是常用的流类型结构图:
字节与流
在对文件的读写操作中,字节流可用于读写二进制文件,字符流用于读写文本文件。所谓二进制文件,指文件无字符编码格式,均由字节(Byte)组成,图片文件、word文档等均为二进制文件。文本文件是一种特殊的二进制文件,也由字节组成,但需要通过特定的字符编码格式读取或写入,否则会出现乱码,后缀名为txt的文件就是典型的文本文件。

File类

File类的对象表示磁盘、目录、文件。其对象的属性包含了文件或目录的相关信息,如名称、长度、所含文件个数等,其方法可以完成对文件或目录的常用管理操作,如创建、删除等。
下面是File类的常用方法:

方法名称参数作用返回值
构造方法String传入文件或目录名,获取对应的文件或目录对象
canRead文件是否可读boolean:是否可读
canWrite文件是否可写boolean:是否可写
delete删除文件或目录boolean:操作结果
exists文件或目录是否存在boolean:是否存在
getAbsolutePath获取绝对路径String:绝对路径
getFreeSpace获取分区的剩余空间long:字节数量
getTotalSpace获取分区的总空间long:字节数量
getUsableSpace获取分区的已用空间long:字节数量
getName获取文件或目录的名称String:文件或目录名称
isDirectory是否为目录boolean:是否为目录
isFile是否为文件boolean:是否为文件
isHidden是否为隐藏文件或目录boolean:是否隐藏
lastModified获取文件最后修改时间long:最后修改时间
length获取文件长度long:字节数量
listFiles获取目录的子目录、文件File[]:子目录和子文件
listRoots获取所有磁盘分区File[]:磁盘分区
mkdir创建目录boolean:是否创建成功
mkdirs创建多级目录boolean:是否创建成功

File类的常用方法

列出磁盘分区和D盘目录

package io;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Una
 * @date 2022/7/20 11:17
 * @description:
 */


public class FileTest {
    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    public static void main(String[] args) {
        /**
         *public static File[] listRoots() {
         *         return fs.listRoots();
         * }
         */
        // 获取当前文件系统的所有磁盘分区
        File[] disks=File.listRoots();
        for (int i = 0; i < disks.length; i++) {
            File disk = disks[i];
            System.out.println(disk.getAbsolutePath() + "盘\t总空间:"
                    + disk.getTotalSpace() / 1024 / 1024 / 1024 + "G\t剩余空间"
                    + disk.getFreeSpace() / 1024 / 1024 / 1024 + "G");
        }
        //获取D盘根目录
        File c = new File("D:");
        if (!c.exists()) {
            System.out.println("D盘不存在");
            return ;
        }
        System.out.println("D盘根目录结构:");
        File[] files = c.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (file.isDirectory()) {
                System.out.print("[目录]" + file.getName());
            }
            if (file.isFile()) {
                System.out.print("[文件]" + file.getName());
                System.out.print("\t大小:" + file.length() / 1024 + "K");
                Date date = new Date(file.lastModified());
                System.out.print("\t修改日期:" + sdf.format(date) + "\t");
                //isHidden()返回值为Boolean
                if (file.isHidden()){
                    System.out.print("[隐藏]");
                }
                //放法canWrite()判断是否可写
                if (!file.canWrite()){
                    System.out.print("[只读]");
                }
            }
            System.out.println();
        }
    }
}

运行结果
运行结果

FileInputStream

FileInputStream;顾名思义,输入流。
使用字节输入流(FileInputStream)读取文件分为以下三个步骤:

  1. 打开文件。
  2. 按字节读取文件。
  3. 关闭文件。
package io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author Una
 * @date 2022/7/20 10:56
 * @description:输入流,读操作
 */


public class FileInput {
    public static void main(String[] args) {
        File file=new File("E:\\java学习\\day20-IO流\\课件\\111111.txt");
        try {
            //打开文件
            FileInputStream fileInputStream=new FileInputStream(file);
            /**
             *  public int read() throws IOException {
             *         return read0();
             *  }
             *  read()一次读一个字节,读取出来的是字节的ASCII码,转换为char型输出,也就是使用一次read读一次,所以使用i接着
             */
            int i=0;
            while ((i=fileInputStream.read())!=-1){//如果i的值为-1说明读到了文件尾,退出循环
                System.out.print((char) i);
            }
            //关闭文件
            fileInputStream.close();

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

结果对比:
结果

结果

BufferedInputStream(文件缓存输入流)

FileInputStream提供的read方法每执行一次均会发出一次IO读取操作,一次读一个字节,效率很低。因此Java提供了缓存输入流(BufferedInputStream),能够在一次IO读取操作中读取多个字节,降低了IO读取的频率,提高了代码效率。

package io;
import java.io.*;
/**
 * @author Una
 * @date 2022/7/20 11:40
 * @description:
 */


public class FileInputBuffer {
    public static void main(String[] args) {
        File file=new File("E:\\java学习\\day20-IO流\\课件\\111111.txt");
        try {
            //打开文件
            FileInputStream fileInputStream=new FileInputStream(file);
            //BufferedInputStream 需要传入的是FileInputStream对象
            BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
            int i=0;
            while ((i= bufferedInputStream.read())!=-1){
                System.out.print((char)i);
            }
            //关闭BufferInputStream
            bufferedInputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

需要注意的是:
① 缓存输入流不能独立使用,需要通过文件输入流进行构建。

② 应使用缓存输入流实例读取文件,如继续使用fis(文件输入流实例),则绕过了缓存,性能不会得到提升。

③ 关闭文件时只需要关闭缓存输入流实例即可。

FileOutputStream(字节输出流)

字节输出流(FileOutputStream)的使用也分为开发文件、输出、关闭文件三部分。

package io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author Una
 * @date 2022/7/20 12:02
 * @description:
 */


public class FileOutput {
    public static void main(String[] args) {
        File file=new File("E:\\java学习\\day20-IO流\\课件\\111111.txt");
        try {
            //打开文件
            //FileOutputStream fos = new FileOutputStream(file, true);
            FileOutputStream fileOutputStream=new FileOutputStream(file);
            //写入,数字代表ASCII码
            fileOutputStream.write(65);
            fileOutputStream.write(66);
            fileOutputStream.write(67);
            //关闭文件
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果:
结果

BufferedOutputStream(缓存输出流)

单独使用文件输出流也存在效率问题,同样可以使用缓存输出流(BufferedOutputStream)进行改善。

package io;
import java.io.*;
/**
 * @author Una
 * @date 2022/7/20 12:13
 * @description:
 */
public class FileOutputBuffer {
    public static void main(String[] args) {
        File file=new File("E:\\java学习\\day20-IO流\\课件\\111111.txt");
        try {
            FileOutputStream fileOutputStream=new FileOutputStream(file);
            BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(fileOutputStream);
            bufferedOutputStream.write(65);
            bufferedOutputStream.write(66);
            bufferedOutputStream.write(67);
            //flush方法用于强制将缓存中内容输出
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

flush()方法:

  1. 缓存输出流会将输出的内容缓存在内存中,如果缓存区已满,那么缓存会自动将数据输出到目的地。如果缓存区数据未满,则需要调用flush方法,将缓存区数据输出到目的地。如果忘记调用flush方法,则不会将内容输出到目的地。
  2. 调用缓存输出流的close方法时会自动执行flush方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值