分享

第九章:Java输入输出流和文件操作

 山峰云绕 2023-05-14 发布于贵州

https://www.toutiao.com/article/7232505586427052544/?log_from=9113ff10be427_1683993923607

在本章中,我们将介绍Java中输入输出流和文件操作的相关知识。输入输出流是Java程序与外部环境进行数据交互的重要方式,而文件操作则是在计算机上读取和写入文件的常见操作。了解输入输出流和文件操作对于开发Java应用程序和处理文件数据非常重要。

9.1 Java的字节流和字符流

在Java中,字节流和字符流是处理输入输出的两种主要流类型。字节流用于以字节为单位进行数据传输,而字符流则以字符为单位进行数据传输。字节流适用于处理二进制数据和非文本文件,而字符流则适用于处理文本数据和字符集编码。

Java提供了以下基本的字节流和字符流类:

  • 字节流:InputStream和OutputStream
  • 字符流:Reader和Writer

9.1.1 字节流(InputStream和OutputStream)

字节流是以字节为单位进行数据读取和写入的流类型。InputStream用于读取字节数据,而OutputStream用于写入字节数据。

示例代码:

// 使用InputStream读取文件
try (InputStream input = new FileInputStream("file.txt")) {
    int data;
    while ((data = input.read()) != -1) {
        // 处理读取的字节数据
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 使用OutputStream写入文件
try (OutputStream output = new FileOutputStream("file.txt")) {
    byte[] data = "Hello, World!".getBytes();
    output.write(data);
} catch (IOException e) {
    e.printStackTrace();
}

9.1.2 字符流(Reader和Writer)

字符流是以字符为单位进行数据读取和写入的流类型。Reader用于读取字符数据,而Writer用于写入字符数据。

示例代码:

// 使用Reader读取文件
try (Reader reader = new FileReader("file.txt")) {
    int data;
    while ((data = reader.read()) != -1) {
        // 处理读取的字符数据
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 使用Writer写入文件
try (Writer writer = new FileWriter("file.txt")) {
    String data = "Hello, World!";
    writer.write(data);
} catch (IOException e) {
    e.printStackTrace();
}

9.1.3 缓冲流(BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter)

为了提高读写性能,Java提供了缓冲流,它们是字节流和字符流的装饰器(Wrapper),可以在字节流和字符流的基础上添加缓冲功能。

示例代码:

// 使用BufferedInputStream读取文件
try (InputStream input = new BufferedInputStream(new FileInputStream("file.txt"))) {
    int data;
    while ((data = input.read()) != -1) {
        // 处理读取的字节数据
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 使用BufferedOutputStream写入文件
try (OutputStream output = new BufferedOutputStream(new FileOutputStream("file.txt")))
{
    String data = "Hello, World!";
    byte[] bytes = data.getBytes();
    try {
        output.write(bytes);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 使用BufferedReader读取文件
try (Reader reader = new BufferedReader(new FileReader("file.txt"))) {
    int data;
    while ((data = reader.read()) != -1) {
        // 处理读取的字符数据
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 使用BufferedWriter写入文件
try (Writer writer = new BufferedWriter(new FileWriter("file.txt"))) {
    String data = "Hello, World!";
    try {
        writer.write(data);
    } catch (IOException e) {
        e.printStackTrace();
    }
} catch (IOException e) {
    e.printStackTrace();
}

缓冲流可以提高读写效率,它们会在内部维护一个缓冲区,减少实际读写文件的次数。

9.2 Java的转换流和打印流

除了基本的字节流和字符流之外,Java还提供了转换流和打印流,它们是对字节流和字符流的功能增强。

9.2.1 转换流(InputStreamReader,OutputStreamWriter)

转换流可以在字节流和字符流之间进行转换。InputStreamReader将字节流转换为字符流,而OutputStreamWriter将字符流转换为字节流。转换流通常用于处理不同字符集编码的数据。

示例代码:

// 使用InputStreamReader读取字节流并转换为字符流
try (InputStream input = new FileInputStream("file.txt");
     Reader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) {
    int data;
    while ((data = reader.read()) != -1) {
        // 处理读取的字符数据
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 使用OutputStreamWriter将字符流转换为字节流并写入文件
try (OutputStream output = new FileOutputStream("file.txt");
     Writer writer = new OutputStreamWriter(output, StandardCharsets.UTF_8)) {
    String data = "Hello, World!";
    try {
        writer.write(data);
    } catch (IOException e) {
        e.printStackTrace();
    }
} catch (IOException e) {
    e.printStackTrace();
}

9.2.2 打印流(PrintStream,PrintWriter)

打印流提供了方便的输出功能,可以将数据直接打印到输出流或文件中。PrintStream和PrintWriter分别用于处理字节流和字符流的打印操作。

示例代码:

// 使用PrintStream将数据打印到控制台
try (PrintStream printStream = new PrintStream(System.out)) {
    printStream.println("Hello, World!");
} catch (IOException e) {
    e.printStackTrace();
}

// 使用PrintWriter将数据打印到文件
try (PrintWriter printWriter = new PrintWriter("file.txt")) {
    printWriter.println("Hello, World!");
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

打印流可以方便地输出各种数据类型,并自动处理换行等格式化操作。

9.3 Java的文件类和文件操作方法

Java提供了File类来操作文件和目录。File类可以用于创建、删除、重命名文件或目录,以及查询文件和目录的属性。

9.3.1 创建文件和目录

可以使用File类的相关方法创建新的文件或目录。

示例代码:

// 创建新文件
File file = new File("file.txt");
try {
    if (file.createNewFile()) {
        System.out.println("文件创建成功");
    } else {
        System.out.println("文件已存在");
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 创建新目录
File dir = new File("mydir");
if (dir.mkdir()) {
    System.out.println("目录创建成功");
} else {
    System.out.println("目录已存在");
}

9.3.2 删除文件和目录

可以使用File类的相关方法删除文件或目录。

示例代码:

// 删除文件
File file = new File("file.txt");
if (file.delete()) {
    System.out.println("文件删除成功");
} else {
    System.out.println("文件不存在");
}

// 删除目录
File dir = new File("mydir");
if (dir.delete()) {
    System.out.println("目录删除成功");
} else {
    System.out.println("目录不存在");
}

9.3.3 重命名文件和目录

可以使用File类的renameTo()方法对文件或目录进行重命名。

示例代码:

// 重命名文件
File file = new File("oldfile.txt");
File newFile = new File("newfile.txt");
if (file.renameTo(newFile)) {
    System.out.println("文件重命名成功");
} else {
    System.out.println("文件重命名失败");
}

// 重命名目录
File dir = new File("olddir");
File newDir = new File("newdir");
if (dir.renameTo(newDir)) {
    System.out.println("目录重命名成功");
} else {
    System.out.println("目录重命名失败");
}

9.3.4 查询文件和目录属性

可以使用File类的相关方法查询文件和目录的属性,如文件大小、最后修改时间等。

示例代码:

// 查询文件属性
File file = new File("file.txt");
System.out.println("文件名:" + file.getName());
System.out.println("文件路径:" + file.getAbsolutePath());
System.out.println("文件大小:" + file.length() + "字节");
System.out.println("最后修改时间:" + new Date(file.lastModified()));

// 查询目录属性
File dir = new File("mydir");
System.out.println("目录名:" + dir.getName());
System.out.println("目录路径:" + dir.getAbsolutePath());
System.out.println("是否是目录:" + dir.isDirectory());
System.out.println("是否是文件:" + dir.isFile());

以上代码可以获取文件和目录的基本属性信息。

9.3.5 文件操作方法

除了上述常见的文件操作外,File类还提供了其他一些常用的方法,如判断文件是否存在、列出目录下的文件等。

示例代码:

// 判断文件是否存在
File file = new File("file.txt");
if (file.exists()) {
    System.out.println("文件存在");
} else {
    System.out.println("文件不存在");
}

// 列出目录下的文件
File dir = new File("mydir");
if (dir.isDirectory()) {
    File[] files = dir.listFiles();
    if (files != null) {
        for (File f : files) {
            System.out.println(f.getName());
        }
    }
}

这些方法可以帮助我们进行文件的判断、查询和操作,方便地进行文件系统的管理。

9.4 Java的序列化与反序列化

Java提供了序列化(Serialization)和反序列化(Deserialization)的机制,可以将对象转换为字节流进行存储或传输,以及将字节流转换回对象。

序列化和反序列化主要通过ObjectOutputStream和ObjectInputStream来实现,它们可以将对象写入输出流或从输入流中读取对象。

示例代码:

// 序列化对象
try (OutputStream output = new FileOutputStream("object.dat");
     ObjectOutputStream objectOutput = new ObjectOutputStream(output)) {
    MyClass object = new MyClass();
    object.setName("John Doe");
    object.setAge(25);
    objectOutput.writeObject(object);
    System.out.println("对象序列化成功");
} catch (IOException e) {
    e.printStackTrace();
}

// 反序列化对象
try (InputStream input = new FileInputStream("object.dat");
     ObjectInputStream objectInput = new ObjectInputStream(input)) {
    MyClass object = (MyClass) objectInput.readObject();
    System.out.println("对象反序列化成功");
    System.out.println("姓名:" + object.getName());
    System.out.println("年龄:" + object.getAge());
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

在上述示例中,我们定义了一个名为MyClass的类,该类实现了Serializable接口,表示该类可以被序列化。然后我们创建了一个对象并将其序列化到文件中,然后再从文件中反序列化出对象,并打印出对象的属性。

需要注意的是,被序列化的对象的类必须实现Serializable接口,否则会抛出NotSerializableException异常。

通过序列化与反序列化,我们可以方便地将对象保存到文件中或通过网络传输,并在需要的时候重新恢复为对象,这在很多应用场景中非常有用。

结语

本章我们介绍了Java的输入输出流和文件操作。我们学习了字节流和字符流的基本概念和用法,以及如何使用缓冲流提高读写效率。我们还学习了转换流和打印流的使用,以及File类的文件和目录操作方法。最后,我们了解了序列化与反序列化的机制,可以将对象转换为字节流进行存储或传输。

输入输出流和文件操作是Java编程中常用的重要知识点,对于开发各种类型的应用程序都非常重要。掌握了这些知识,可以更好地处理数据的读取、写入和管理。在实际开发中,我们经常需要与文件进行交互,读取配置文件、保存用户数据等操作都需要用到输入输出流和文件操作。

在学习本章内容后,你应该对Java的输入输出流和文件操作有了较为全面的了解。你学习了不同类型的流及其特点,掌握了文件的创建、删除、重命名和属性查询等操作方法。此外,你还学习了如何序列化和反序列化对象,实现对象的持久化和传输。

输入输出流和文件操作在实际开发中非常常见,特别是在处理文件、网络通信等场景下。通过良好的文件管理和数据读写方式,可以提高程序的可靠性和性能。

希望本章的内容能够帮助你掌握Java的输入输出流和文件操作,为你的Java编程之路提供一定的指引。在接下来的学习中,你可以继续深入了解Java的多线程编程、网络编程、数据库编程等知识点,进一步扩展你的Java技能。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多