文件IO操作

一、什么是文件

1、定义

在计算机领域,文件是存储在存储设备(如硬盘、固态驱动器、闪存驱动器、光盘等)上的一组相关信息或数据的集合。这些信息或数据可以是文本、图像、音频、视频、程序指令、数据库记录等多种类型。文件是计算机操作系统管理数据的基本单位,允许用户和组织以逻辑方式存储、访问和修改信息。

2、主要部分

  1. 文件名:用于唯一标识文件的名称,通常由用户或程序指定。文件名可以包含字母、数字、空格和一些特殊字符,但具体规则取决于操作系统。

  2. 文件扩展名:位于文件名末尾的点(.)之后的部分,用于指示文件的类型或格式。例如,.txt 表示文本文件,.jpg 表示JPEG格式的图像文件,.mp3 表示MP3格式的音频文件等。

  3. 文件内容:文件的实际数据或信息,可以是文本、二进制数据或其他形式的数据。

  4. 文件属性:除了文件名和扩展名之外,文件还包含一系列属性,如文件大小(占用的存储空间量)、创建日期和时间、修改日期和时间、访问日期和时间、文件权限(谁可以读取、写入或执行文件)等。

  5. 目录:为了将文件分类,操作系统提供了一类特殊的文件——目录(也叫文件夹),用以容纳各类的文件。目录也是文件,因此归属于同类的目录也可以放在统筹的目录中,形成嵌套式的树形结构,这样做使文件管理更加便利。

  6. 文件路径:用于定位文件在存储设备上的位置的信息。在大多数操作系统中,文件路径可以是绝对路径(从根目录开始的完整路径)或相对路径(相对于当前工作目录的路径)。

操作系统提供了文件管理功能,允许用户创建、打开、读取、写入、复制、移动、删除和重命名文件。这些操作通过文件系统实现,文件系统是操作系统中用于组织和存储文件的结构和机制。不同的操作系统可能支持不同的文件系统,如FAT、NTFS(Windows)、HFS+(Mac OS)、ext4(Linux)等。

二、文件路径

文件路径是文件在计算机存储系统中的位置表示,用于指向、定位或访问文件。它通常由目录(或文件夹)名和文件名组成,目录和目录之间、目录和文件名之间使用特定的分隔符(如在Windows系统中是反斜杠\,在Unix、Linux及MacOS系统中是正斜杠/)分隔。文件路径可以是绝对路径或相对路径。

1、绝对路径

绝对路径是从根目录(或称为顶级目录)开始的完整路径。它包含了从根目录到目标文件所需经过的所有目录和子目录的完整列表,因此,无论当前工作目录是什么,使用绝对路径都可以定位到文件。

例子(Windows):

C:\Users\Username\Documents\file.txt

这里,C: 是根目录(驱动器),\Users\Username\Documents\ 是从根目录到文件所在目录的路径,file.txt 是文件名。

例子(Unix/Linux/MacOS):

/home/username/documents/file.txt

这里,/ 是根目录,/home/username/documents/ 是从根目录到文件所在目录的路径,file.txt 是文件名。

2、相对路径

相对路径是从当前工作目录(或称为当前目录)开始到目标文件的路径。它不包含从根目录到当前目录的完整路径,因此,相对路径的有效性取决于当前工作目录。

例子(Windows):
如果当前工作目录是 C:\Users\Username\Documents,则相对路径 .\file.txt 或仅 file.txt 都可以指向 C:\Users\Username\Documents\file.txt

例子(Unix/Linux/MacOS):
如果当前工作目录是 /home/username/documents,则相对路径 ./file.txt 或仅 file.txt 都可以指向 /home/username/documents/file.txt

注意,. 表示当前目录,.. 表示上一级目录。因此,相对路径可以使用 .. 来向上回溯目录结构。

3、注意事项

  • 路径中的大小写敏感性取决于操作系统。Windows通常不区分大小写,而Unix、Linux和MacOS则区分大小写
  • 路径中的空格和特殊字符可能需要特殊处理,如在命令行中使用时可能需要用引号括起来或进行转义。
  • 目前window系统也支持使用 / 作为分隔符。

三、Java中的文件操作

1、File 类

  • 构造方法

    构造方法描述
    File(String pathname)通过给定的路径名字符串 (可以是绝对路径或相对路径)来创建新的 File 实例。
    File(String parent, String child)根据父路径名字符串和子路径名字符串来创建新的 File 实例。如果父路径名为 null,则新创建的 File 实例将使用绝对路径名 child
    File(File parent, String child)根据 File 对象表示的父目录和子路径名字符串来创建新的 File 实例。这允许你基于已经存在的 File 对象来构建新的路径。
    File(URI uri)通过将给定的 file: URI 转换为抽象路径名来创建新的 File 实例。注意,这里的 URI 必须是 file: 协议的 URI,否则将抛出 IllegalArgumentException

    请注意,这些构造方法中的路径名或 URI 指定的文件或目录不需要实际存在;File 对象仅表示一个路径名。你可以使用 File 类提供的方法来检查文件或目录是否存在,或者执行其他与文件或目录相关的操作。

  • 常见方法
    以下是用表格形式列举的File类的常见方法,这些方法在Java中用于操作文件和目录:

    方法名描述返回值类型备注
    exists()检查文件或目录是否存在boolean如果文件或目录存在,则返回true
    isFile()判断File对象是否表示一个文件(而不是目录)boolean如果是文件,则返回true
    isDirectory()判断File对象是否表示一个目录boolean如果是目录,则返回true
    getName()返回文件或目录的名称String返回路径名中的最后一部分
    getParent()返回文件或目录的父路径名字符串String如果没有父目录,则返回null
    getPath()返回文件或目录的路径名字符串String返回创建File对象时使用的路径名
    getAbsolutePath()返回文件或目录的绝对路径名字符串String解析为绝对路径名
    createNewFile()创建新文件,如果文件已存在则不创建boolean如果文件创建成功,则返回true
    delete()删除文件或目录boolean如果删除成功,则返回true
    mkdir()创建目录boolean如果目录创建成功,则返回true
    mkdirs()创建目录,包括所有必需的父目录boolean如果目录创建成功,则返回true
    length()返回文件的大小(以字节为单位)long如果文件不存在,则返回0L
    list()返回目录中的文件和目录名字符串数组String[]调用此方法的File对象必须表示一个目录
    listFiles()返回目录中的文件和目录File对象数组File[]调用此方法的File对象必须表示一个目录
    lastModified()返回文件或目录的最后修改时间long以毫秒为单位,自1970年1月1日00:00:00 GMT以来的时间
    canRead()判断文件或目录是否可读boolean取决于Java虚拟机的安全管理器
    canWrite()判断文件或目录是否可写boolean取决于Java虚拟机的安全管理器
    isHidden()判断文件或目录是否为隐藏文件或目录boolean在某些操作系统中,隐藏文件或目录可能不被列出
    renameTo(File dest)重命名文件或目录boolean如果重命名成功,则返回true
    getCanonicalPath()返回File对象的修饰过的绝对路径String它消除了路径名中的冗余名称(如 ...),并将路径分隔符解析为适当的分隔符(在 UNIX 系统中是 /,在 Windows 系统中是 \
    deleteOnExit()根据File对象,标注⽂件将被删除,删除动作会到JVM运⾏结束时才会进行void

    请注意,上述方法中的大多数都可能会抛出SecurityException,如果安全管理器存在并且其checkReadcheckWritecheckDeletecheckExec方法不允许进行指定的操作。此外,一些方法(如createNewFile()delete()等)还可能抛出IOException,但File类本身的方法通常不会直接读取或写入文件内容,因此这些异常通常不会由File类的方法直接抛出。然而,当与FileInputStreamFileOutputStream等类结合使用时,可能会遇到IOException

2、输入输出流

数据流(data stream)是一组有序、有起点和终点的字节数据序列,包括输入流和输出流。

  • 输入流是指从某个数据源(如文件、键盘、网络等)读取数据的通道。当程序需要从外部世界获取数据时,就会使用输入流。输入流允许程序以顺序的方式读取数据,直到到达数据源的末尾。
  • 输出流是指将数据写入到某个目的地(如文件、屏幕、网络等)的通道。当程序需要将数据发送到外部世界时,就会使用输出流。输出流允许程序以顺序的方式写入数据,直到数据被完全写入目的地。
    在这里插入图片描述
    在输入输出流也分为字节流字符流两部分。

2.1、字节流

字节流(Byte Stream)是计算机中一种基本的数据传输方式,它是以字节(Byte)为单位的有序序列。在计算机系统中,所有数据最终都以字节的形式进行表示、存储和传输,因此字节流是处理这些数据的基础。

InputStream 类
  • 方法

    返回值类型方法签名说明
    intread()读取⼀个字节的数据,返回-1代表已经完全读完了
    intread( byte[] b)最多读取b.length字节的数据到b中,返回实际读到的数量;-1代表以及读完了
    intread( byte[] b, int off, int len)最多读取len-off字节的数据到b中,放在从off开始,返回实际读到的数量;-1代表以及读完了
    voidclose()关闭字节流
  • 说明
    InputStream 只是⼀个抽象类,要使⽤还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输⼊设备都可以对应⼀个 InputStream 类,我们现在只关心从文件中读取,所以使用FileInputStream

FileInputStream
  • 构造函数
方法签名说明
FileInputStream( Filefile )利用File构造⽂件输⼊流
FileInputStream( String path)利用文件路径构造⽂件输⼊流
示例

以下是两种 读的方法,第二种方法效率更高。

public class Main {

    //需要先在项⽬⽬录下准备好⼀个hello.txt的⽂件,⾥⾯填充"Hello"的内容
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            while (true) {
                int b = is.read();
                if (b == -1) {
                    //代表⽂件已经全部读完

                    break;
                }

                System.out.printf("%c", b);
            }
        }
    }
}
//需要先在项⽬⽬录下准备好⼀个hello.txt的⽂件,⾥⾯填充 "Hello" 的内容

public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            byte[] buf = new byte[1024];
            int len;

            while (true) {
                len = is.read(buf);
                if (len == -1) {
                    //代表⽂件已经全部读完

                    break;
                }

                for (int i = 0; i < len; i++) {
                    System.out.printf("%c", buf[i]);
                }
            }
        }
    }
}
OutputStream
  • 方法

    返回值方法签名说明
    voidwrite( int b )写⼊要给字节的数据
    voidwrite( byte[] b )将b这个字节数组中的数据全部写入os中
    intwrite( byte[] b, int off, int len )将b这个字节数组中从 off 开始的数据写入os中,⼀共写len个
    voidclose( )关闭字节流
    voidflush( )重要:我们知道I/O的速度是很慢的,所以,大多的OutputStream为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的⼀个指定区域⾥,直到该区域满了或者其他指定条件时才真正将数据写⼊设备中,这个区域⼀般称为缓冲区。但造成⼀个结果,就是我们写的数据,很可能会遗留⼀部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。
  • 说明
    OutputStream 同样只是⼀个抽象类,要使用还需要具体的实现类。我们现在还是只关心写⼊⽂件中,所以使 FileOutputStream

FileOutputStream
  • 构造函数

    方法签名说明
    FileOutputStream( Filefile )利用File构造⽂件输出流
    FileOutputStream( String path)利用文件路径构造⽂件输出流
  • 示例

    示例1

     import java.io.*;
     public class Main {
         public static void main(String[] args) throws IOException {
             try (OutputStream os = new FileOutputStream("output.txt")) {
                 os.write('H');
                 os.write('e');
                 os.write('l');
                 os.write('l');
                 os.write('o');
                 // 
                 不要忘记
                         flush
                 os.flush();
             }
         }
     }
    

2.2、字符流

字符流(Character Stream)是由一系列连续的字符组成的集合,它主要用于处理文本数据。

Reader 类

FileReaderReader类的一个子类,用于从文件中读取字符数据。以下是一个使用FileReader读取文件内容并输出到控制台的例子:

import java.io.FileReader;
import java.io.IOException;

public class FileReaderExample {
    public static void main(String[] args) {
        FileReader fileReader = null;
        try {
            // 创建FileReader对象,指定要读取的文件路径
            fileReader = new FileReader("input.txt");
            int data;
            // 读取文件中的字符,直到文件末尾
            while ((data = fileReader.read()) != -1) {
                // 将读取到的字符转换为int类型,并强制转换为char类型后输出
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流资源
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

`

Writer 类
  • FileWriterWriter类的一个子类,用于向文件中写入字符数据。以下是一个使用FileWriter将数据写入到文件的例子:

    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileWriterExample {
        public static void main(String[] args) {
            FileWriter fileWriter = null;
            try {
                // 创建FileWriter对象,指定要写入的文件路径
                fileWriter = new FileWriter("output.txt");
                // 写入字符串到文件
                fileWriter.write("Hello, World!");
                // 强制刷新缓冲区中的数据到文件中
                fileWriter.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 关闭流资源
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  • BufferedReaderBufferedWriter分别是ReaderWriter的子类,它们通过内部缓冲区来提高字符流的读写效率。以下是一个使用BufferedReader读取文件和BufferedWriter写入文件的例子:

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class BufferedStreamsExample {
        public static void main(String[] args) {
            BufferedReader br = null;
            BufferedWriter bw = null;
            try {
                // 读取文件
                br = new BufferedReader(new FileReader("input.txt"));
                // 写入文件
                bw = new BufferedWriter(new FileWriter("output.txt"));
                String line;
                // 逐行读取并写入
                while ((line = br.readLine()) != null) {
                    bw.write(line);
                    bw.newLine(); // 添加新行
                }
    
  • FileWriter的构造方法还允许在文件末尾追加数据,而不是覆盖原有数据。以下是一个使用FileWriter追加数据到文件的例子:

    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileWriterAppendExample {
        public static void main(String[] args) {
            FileWriter fileWriter = null;
            try {
                // 创建FileWriter对象,指定要写入的文件路径,并设置append模式为true
                fileWriter = new FileWriter("output.txt", true);
                // 追加字符串到文件
                fileWriter.write("\nNew line appended.");
                // 强制刷新缓冲区中的数据到文件中
                fileWriter.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 关闭流资源
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值