Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误和异常

Java 多线程

Java 同步

Java 网络编程

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 其他

Java APIs 和框架

Java 类引用

Java 有用资源

Java - 文件和I/O



java.io 包包含几乎所有你可能需要在 Java 中执行输入和输出 (I/O) 的类。所有这些流都表示输入源和输出目标。java.io 包中的流支持多种数据,例如基本类型、对象、本地化字符等。

流可以定义为一系列数据。流有两种:

  • InputStream - InputStream 用于从源读取数据。

  • OutputStream - OutputStream 用于将数据写入目标。

Streams

Java 提供了强大而灵活的与文件和网络相关的 I/O 支持,但本教程涵盖了与流和 I/O 相关的非常基本的功能。我们将逐一查看最常用的示例:

字节流

Java 字节流用于执行 8 位字节的输入和输出。虽然有很多与字节流相关的类,但最常用的类是FileInputStreamFileOutputStream。以下是一个使用这两个类将输入文件复制到输出文件的示例:

示例

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {

   public static void main(String args[]) throws IOException {  
      FileInputStream in = null;
      FileOutputStream out = null;

      try {
         in = new FileInputStream("input.txt");
         out = new FileOutputStream("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

现在让我们有一个名为input.txt 的文件,其内容如下:

This is test for copy file.

下一步,编译上述程序并执行它,这将导致创建一个 output.txt 文件,其内容与 input.txt 中的内容相同。因此,让我们将上述代码放入 CopyFile.java 文件中,并执行以下操作:

$javac CopyFile.java
$java CopyFile

字符流

Java 字节流用于执行 8 位字节的输入和输出,而 Java 字符流用于执行 16 位 Unicode 的输入和输出。虽然有很多与字符流相关的类,但最常用的类是FileReaderFileWriter。虽然内部 FileReader 使用 FileInputStream,FileWriter 使用 FileOutputStream,但这里的主要区别是 FileReader 一次读取两个字节,FileWriter 一次写入两个字节。

我们可以重写上面的示例,它使用这两个类来复制一个输入文件(包含 Unicode 字符)到一个输出文件:

示例

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

public class CopyFile {

   public static void main(String args[]) throws IOException {
      FileReader in = null;
      FileWriter out = null;

      try {
         in = new FileReader("input.txt");
         out = new FileWriter("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

现在让我们有一个名为input.txt 的文件,其内容如下:

This is test for copy file.

下一步,编译上述程序并执行它,这将导致创建一个 output.txt 文件,其内容与 input.txt 中的内容相同。因此,让我们将上述代码放入 CopyFile.java 文件中,并执行以下操作:

$javac CopyFile.java
$java CopyFile

标准流

所有编程语言都支持标准 I/O,用户程序可以从键盘获取输入,然后在计算机屏幕上产生输出。如果您了解 C 或 C++ 编程语言,那么您一定了解三个标准设备 STDIN、STDOUT 和 STDERR。类似地,Java 提供以下三个标准流:

  • 标准输入 - 这用于向用户程序提供数据,通常使用键盘作为标准输入流,表示为System.in

  • 标准输出 − 用于输出用户程序产生的数据,通常使用计算机屏幕作为标准输出流,表示为System.out

  • 标准错误 − 用于输出用户程序产生的错误数据,通常使用计算机屏幕作为标准错误流,表示为System.err

下面是一个简单的程序,它创建了一个InputStreamReader来读取标准输入流,直到用户输入“q”为止:

示例

import java.io.InputStreamReader;
public class ReadConsole {
   public static void main(String args[]) throws IOException {
      InputStreamReader cin = null;

      try {
         cin = new InputStreamReader(System.in);
         System.out.println("Enter characters, 'q' to quit.");
         char c;
         do {
            c = (char) cin.read();
            System.out.print(c);
         } while(c != 'q');
      }finally {
         if (cin != null) {
            cin.close();
         }
      }
   }
}

让我们将以上代码保存在ReadConsole.java文件中,并尝试编译和执行它,如下面的程序所示。这个程序会持续读取并输出相同的字符,直到我们按下'q':

$javac ReadConsole.java
$java ReadConsole
Enter characters, 'q' to quit.
1
1
e
e
q
q

文件读取和写入

如前所述,流可以定义为一系列数据。InputStream用于从源读取数据,OutputStream用于将数据写入目标。

以下是处理输入和输出流的类层次结构。

Files IO

两个重要的流是FileInputStreamFileOutputStream,本教程将对此进行讨论。

FileInputStream

此流用于从文件读取数据。可以使用关键字new创建对象,并且有多种类型的构造函数可用。

下面的构造函数采用文件名(字符串)来创建一个输入流对象以读取文件:

InputStream f = new FileInputStream("C:/java/hello");

下面的构造函数采用文件对象来创建一个输入流对象以读取文件。首先,我们使用File()方法创建文件对象,如下所示:

File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);

一旦你拥有了InputStream对象,就可以使用一系列辅助方法来读取流或对流执行其他操作。

序号 方法及描述
1

public void close() throws IOException{}

此方法关闭文件输出流。释放与文件关联的任何系统资源。抛出IOException异常。

2

protected void finalize()throws IOException {}

此方法清理与文件的连接。确保当没有更多对该流的引用时,调用此文件输出流的close方法。抛出IOException异常。

3

public int read(int r)throws IOException{}

此方法从InputStream读取指定字节的数据。返回一个int值。返回下一个数据字节,如果到了文件末尾则返回-1。

4

public int read(byte[] r) throws IOException{}

此方法从输入流读取r.length个字节到数组中。返回读取的总字节数。如果到了文件末尾,则返回-1。

5

public int available() throws IOException{}

给出可以从此FileInputStrem读取的字节数。返回一个int值。

还有其他重要的输入流可用,更多详情请参考以下链接:

FileOutputStream

FileOutputStream用于创建文件并将数据写入其中。如果文件不存在,此流将在打开它进行输出之前创建它。

以下是可以用来创建FileOutputStream对象的两个构造函数。

下面的构造函数采用文件名(字符串)来创建一个输入流对象以写入文件:

OutputStream f = new FileOutputStream("C:/java/hello") 

下面的构造函数采用文件对象来创建一个输出流对象以写入文件。首先,我们使用File()方法创建文件对象,如下所示:

File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

一旦你拥有了OutputStream对象,就可以使用一系列辅助方法来写入流或对流执行其他操作。

序号 方法及描述
1

public void close() throws IOException{}

此方法关闭文件输出流。释放与文件关联的任何系统资源。抛出IOException异常。

2

protected void finalize()throws IOException {}

此方法清理与文件的连接。确保当没有更多对该流的引用时,调用此文件输出流的close方法。抛出IOException异常。

3

public void write(int w)throws IOException{}

此方法将指定的字节写入输出流。

4

public void write(byte[] w)

将w.length个字节从提到的字节数组写入OutputStream。

还有其他重要的输出流可用,更多详情请参考以下链接:

示例

以下示例演示了InputStream和OutputStream:

import java.io.OutputStream;

public class fileStreamTest {

   public static void main(String args[]) {
   
      try {
         byte bWrite [] = {11,21,3,40,5};
         OutputStream os = new FileOutputStream("test.txt");
         for(int x = 0; x < bWrite.length ; x++) {
            os.write( bWrite[x] );   // writes the bytes
         }
         os.close();
     
         InputStream is = new FileInputStream("test.txt");
         int size = is.available();

         for(int i = 0; i < size; i++) {
            System.out.print((char)is.read() + "  ");
         }
         is.close();
      } catch (IOException e) {
         System.out.print("Exception");
      }	
   }
}

以上代码将创建文件test.txt并将给定的数字以二进制格式写入其中。标准输出屏幕上的输出也将相同。

文件导航和I/O

我们将学习其他一些类,以了解文件导航和I/O的基础知识。

Java中的目录

目录是一个File,它可以包含其他文件和目录的列表。您可以使用File对象创建目录,列出目录中可用的文件。有关完整详细信息,请查看可以在File对象上调用的所有方法以及与目录相关的那些方法的列表。

创建目录

有两个有用的File实用程序方法可用于创建目录:

  • mkdir( )方法创建一个目录,成功时返回true,失败时返回false。失败表示File对象中指定的路径已存在,或者由于整个路径尚不存在而无法创建目录。

  • mkdirs()方法创建目录及其所有父目录。

以下示例创建"/tmp/user/java/bin"目录:

示例

import java.io.File;

public class CreateDir {

   public static void main(String args[]) {
      String dirname = "/tmp/user/java/bin";
      File d = new File(dirname);
      
      // Create directory now.
      d.mkdirs();
   }
}

编译并执行以上代码以创建"/tmp/user/java/bin"。

注意 − Java会根据约定自动处理UNIX和Windows上的路径分隔符。如果您在Windows版本的Java上使用正斜杠(/),路径仍然可以正确解析。

列出目录

您可以使用File对象提供的list( )方法列出目录中所有可用的文件和目录,如下所示:

示例

import java.io.File;

public class ReadDir {

   public static void main(String[] args) {
      File file = null;
      String[] paths;
  
      try {      
         // create new file object
         file = new File("/tmp");

         // array of files and directory
         paths = file.list();

         // for each name in the path array
         for(String path:paths) {
            // prints filename and directory name
            System.out.println(path);
         }
      } catch (Exception e) {
         // if any error occurs
         e.printStackTrace();
      }
   }
}

这将根据/tmp目录中可用的目录和文件产生以下结果:

输出

test1.txt
test2.txt
ReadDir.java
ReadDir.class
广告