Java文件操作和IO示例详解

 更新时间:2024年12月26日 10:21:58   作者:乌啼霜满天249  
这篇文章主要介绍了Java中通过java.io.File类对文件和目录进行抽象描述,包括创建、删除、重命名等操作,同时介绍了文件内容的读写,需要的朋友可以参考下

Java中通过java.io.File类来对一个文件(包括目录)进行抽象的描述.注意,有File对象,并不代表真实存在该文件.

一、File概述

File类的构造方法

有四种重载方式,通常使用如下:

File(String pathname) //指定文件(或目录)名和路径创建文件对象

File file =new File("hello.text");  //在当前目录创建文件对象

File file =new File("JAVA"); //在当前目录创建一个目录对象

File file=new File("D:\\Java");  //指明详细的路径以及目录名,请注意双斜线

方法

代码示例

示例1:观察get系列的观点与差异:

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("..\\hello-world.txt"); // 并不要求该文件真实存在
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
   }
}

运行结果

..

hello-world.txt

..\hello-world.txt

D:\代码练习\文件示例1\..\hello-world.txt

D:\代码练习\hello-world.txt

示例2 普通文件的创建、删除

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("hello-world.txt"); // 要求该文件不存在,才能看到相同
的现象
        System.out.println(file.exists());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
   }
}

运行结果 

false

false

false

true

true

false

true

false

示例3 普通文件的删除 

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("some-file.txt"); // 要求该文件不存在,才能看到相同的现
象
        System.out.println(file.exists());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        System.out.println(file.delete());
        System.out.println(file.exists());
   }
}

运行结果

false

true

true

true

false

示例4 观察 deleteOnExit 的现象 

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("some-file.txt"); // 要求该文件不存在,才能看到相同的现
象
        System.out.println(file.exists());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        file.deleteOnExit();
        System.out.println(file.exists());
   }
}

示例5  观察目录的创建

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File dir = new File("some-dir"); // 要求该目录不存在,才能看到相同的现象
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        System.out.println(dir.mkdir());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
   }
}

运行结果

false

false

true

true

false

示例6  观察目录创建2

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        System.out.println(dir.mkdir());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
   }
}

运行结果

false

false

false

false

false

mkdir() 的时候,如果中间目录不存在,则无法创建成功; mkdirs() 可以解决这个问题 

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        System.out.println(dir.mkdirs());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
   }
}

 运行结果

false

false

true

true

false

示例7  观察文件重命名.

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("some-file.txt"); // 要求 some-file.txt 得存在,可以
是普通文件,可以是目录
        File dest = new File("dest.txt");   // 要求 dest.txt 不存在
        System.out.println(file.exists());
        System.out.println(dest.exists());
        System.out.println(file.renameTo(dest));
        System.out.println(file.exists());
        System.out.println(dest.exists());
   }
}

运行结果 

true

false

true

false

true

 二、文件内容的读写 —— 数据流 

输入流(InputStream)概述.

方法

修饰符及

返回值类

方法签名

说明

int

read()

读取一个字节的数据,返回 -1 代表已经完全读完了

int

read(byte[] b)

最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了

int

read(byte[] b,

int off, int len)

最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返

回实际读到的数量; -1 代表以及读完了

void

close()

关闭字节流

InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream

利用FileInputStream 从文件中读取

构造方法

签名说明

FileInputStream(File file)

利用 File 构造文件输入流

FileInputStream(String name)

利用文件路径构造文件输入流

代码示例

示例1

将文件完全读完的两种方式。相比较而言,后一种的 IO 次数更少,性能更好

import java.io.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "Hello" 的内容
public class Main {
    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);
           }
       }
   }
}
import java.io.*;
// 需要先在项目目录下准备好一个 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]);
               }
           }
       }
   }
}

示例2

这里我们把文件内容中填充中文看看,注意,写中文的时候使用 UTF-8 编码。 hello.txt 中填写 " 你好中国"

注意:这里我利用了这几个中文的 UTF-8 编码后长度刚好是 3 个字节和长度不超过 1024 字节的现状,但这种方式并不是通用的

import java.io.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
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;
               }
                // 每次使用 3 字节进行 utf-8 解码,得到中文字符
                // 利用 String 中的构造方法完成
                // 这个方法了解下即可,不是通用的解决办法
                for (int i = 0; i < len; i += 3) {
                    String s = new String(buf, i, 3, "UTF-8");
                    System.out.printf("%s", s);
               }
           }
       }
   }
}

利用 Scanner 进行字符读取

上述例子中,我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类。

构造方法说明

Scanner(InputStream is, String charset)

使用 charset 字符集进行 is 的扫描读取

import java.io.*;
import java.util.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
           try (Scanner scanner = new Scanner(is, "UTF-8")) {
               while (scanner.hasNext()) {
                   String s = scanner.next();
                   System.out.print(s);
               }
           }
       }
   }
}

输出流OutputStream 概述

方法

修饰 符及 返回 值类 

方法签名

说明

void

write(int b)

写入要给字节的数据

void

write(byte[] b)

将 b 这个字符数组中的数据全部写入 os 中

int

write(byte[] b, int off, int len)

将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个

void

close()

关闭字节流

void

flush()

重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 

了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的

一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写 入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的

数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,

调用 flush (刷新)操作,将数据刷到设备中。

OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream

利用 OutputStreamWriter 进行字符写入 

示例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

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

示例3

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            byte[] b = new byte[] {
               (byte)'G', (byte)'o', (byte)'o', (byte)'d', (byte)'B', 
(byte)'a', (byte)'d'
           };
            os.write(b, 0, 4);
          
            // 不要忘记 flush
            os.flush();
       }
   }
}

示例4

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
           String s = "Nothing";
            byte[] b = s.getBytes();
            os.write(b);
          
            // 不要忘记 flush
            os.flush();
       }
   }
}

示例5

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            String s = "你好中国";
            byte[] b = s.getBytes("utf-8");
         os.write(b);
            // 不要忘记 flush
            os.flush();
       }
   }
}

利用 PrintWriter 输出 

上述,我们其实已经完成输出工作,但总是有所不方便,我们接来下将 OutputStream 处理下,使用

PrintWriter 类来完成输出,因为

PrintWriter 类中提供了我们熟悉的 print/println/printf 方法

OutputStream os = ...;
OutputStreamWriter osWriter = new OutputStreamWriter(os, "utf-8"); // 告诉它,我
们的字符集编码是 utf-8 的
PrintWriter writer = new PrintWriter(osWriter);
// 接下来我们就可以方便的使用 writer 提供的各种方法了
writer.print("Hello");
writer.println("你好");
writer.printf("%d: %s\n", 1, "没什么");
// 不要忘记 flush
writer.flush();

 示例1

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-
8")) {
                try (PrintWriter writer = new PrintWriter(osWriter)) {
                    writer.println("我是第一行");
                    writer.print("我的第二行\r\n");
                    writer.printf("%d: 我的第三行\r\n", 1 + 1);
                    writer.flush();
               }
           }
       }
   }
}

总结 

到此这篇关于Java文件操作和IO的文章就介绍到这了,更多相关Java文件操作和IO内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot项目实用功能之实现自定义参数解析器

    SpringBoot项目实用功能之实现自定义参数解析器

    这篇文章主要介绍了SpringBoot项目实用功能之实现自定义参数解析器,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • MyBatis-Plus雪花算法实现源码解读

    MyBatis-Plus雪花算法实现源码解读

    雪花算法是一种用于生成唯一标识符(ID)的分布式算法,雪花算法的设计目标是在分布式系统中生成全局唯一的ID,同时保证ID的有序性和趋势递增,这篇文章主要介绍了MyBatis-Plus雪花算法实现源码解析,需要的朋友可以参考下
    2023-12-12
  • Java使用poi实现excel的导入操作指南

    Java使用poi实现excel的导入操作指南

    使用Apache Poi是一种流行且广泛使用的方式,可以帮助开发人员直接从Java代码中读取、写入和处理Excel文件,因此在这篇文章我们将着重介绍如何实现excel的导入,感兴趣的朋友可以跟着小编一起来学习
    2023-06-06
  • 详解如何在Java中重写equals()和hashCode()方法

    详解如何在Java中重写equals()和hashCode()方法

    在 Java 中,equals() 和 hashCode() 方法是 Object 类中定义的重要方法,它们用于比较对象的相等性以及计算对象的哈希值,本文将详细介绍如何在 Java 中重写 equals() 和 hashCode() 方法,并讨论其最佳实践,需要的朋友可以参考下
    2024-08-08
  • java日期相关类实例详解

    java日期相关类实例详解

    这篇文章主要介绍了java日期相关类实例详解,小编觉得还是挺不错的,这里分享给大家,供需要的朋友参考。
    2017-10-10
  • 五个Java中线程池使用不当的避坑指南

    五个Java中线程池使用不当的避坑指南

    线程池是 Java 多线程编程中的一个重要概念,它可以有效地管理和复用线程资源,提高系统的性能和稳定性,本文将介绍线程池使用不当的五个坑,以及如何避免和解决它们,希望对大家有所帮助
    2024-02-02
  • 深入理解springboot中配置文件application.properties

    深入理解springboot中配置文件application.properties

    本文主要介绍了springboot中配置文件application.properties,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 使用JDBC连接Mysql 8.0.11出现了各种错误的解决

    使用JDBC连接Mysql 8.0.11出现了各种错误的解决

    这篇文章主要介绍了使用JDBC连接Mysql 8.0.11出现了各种错误的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • mybatis源码解读之executor包语句处理功能

    mybatis源码解读之executor包语句处理功能

    这篇文章主要介绍了executor包语句处理功能,mybatis中支持三种语句类型,不同语句类型支持的变量符号不同,下文详细内容,需要的小伙伴可以参考一下
    2022-02-02
  • 一文详解Spring是怎样处理循环依赖的

    一文详解Spring是怎样处理循环依赖的

    循环依赖简单理解就是A,B 两个bean相互依赖,A依赖B,B依赖A,A->B、B->A大概就是这样,这篇文章主要介绍了Spring是怎样处理循环依赖的,文中通过代码示例给大家介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2024-01-01

最新评论