Java快速入门(25) - 文件和IO操作

前言

Java中java.io包几乎包含了所有我们需要用到的和输入输出(Input和Output, 即I/O)操作相关的类。所有这些输入输出操作都包含了输入流和输出流,java.io包中的流支持很多类型的数据,例如基础数据类型、对象和各地语言字符等等。

流(stream)可以定义为一序列的数据。流可以分为两种:

  • 输入流InputStream - InputStream可以用来从数据源读取数据。
  • 输出流OutputStream - OutputStream可以用来将数据写入文件。

在这里插入图片描述

Java为与文件和网络相关的I/O提供了强大而灵活的支持,不过本教程只涵盖了与流和I/O相关的基本的功能。我们来逐一学习常用的几种I/O操作。

字节流

Java字节流被用于操作8比特位字节的输入和输出。尽管有很多类都与字节流相关,但最常用的是FileInputStream和FileOutputStream。下面程序使用了这两个类来将输入文件复制到输出文件中。

程序实例

import java.io.*;
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

字符流

Java字节流用于处理8比特位字节的输入和输出,而Java字符流用于处理16比特位unicode的输入和输出。尽管有很多类与字符流相关,但最常用的是FileReader和FileWriter类。虽然从底层实现上来看,FileReader类使用的是FileInputStream类,而FileWriter使用的是FileOutPutStream类,但是两者主要的差别是FileReader每次读两个字节,而FileWriter每次写两个字节。
我们可以将上面复制输入文件的程序实例改写为FileReader和FileWriter来实现。

程序实例

import java.io.*;
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.java

标准流

所有的编程语言都提供标准的I/O,用户的程序可以使用标准I/O流来从键盘输入、从电脑屏幕输出。如果你了解C或C++语言的话,那你一定知道有3个标准的输入输出:STDIN、STDOUT和STDERR。与其相似,Java也提供3中标准流:

  • 标准输入流 - 用于将数据馈送到用户程序,通常将键盘用作标准输入流,其调用为System.in。
  • 标准输出流 - 用于将输出用户程序产生的数据,通常是使用电脑屏幕来展示标准输出流,其调用为System.out。
  • 标准错误流 - 用于输出用户程序产生的错误数据,通常是使用电脑屏幕来展示标准错误流,其调用为System.err。

下面是一个简单的程序,创建了InputStreamReader类的对象来读取标准输入流数据,直到用户按“q”键。

程序实例

import java.io.*;
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

读取文件

如前文所述,流(stream)可以被定义为一序列的数据。InputStream用于从文件读取数据,OutputStream用于将数据写入目标文件。
下图是Java中用于处理输入输出流的类及层次。
在这里插入图片描述

其中,两个重要的处理流的类是FileInputStream和FileOutputStream,下文将会对这两个类进行介绍。

FileInputStream

FileInputStream类用来从文件读取数据。FileInputStream类的对象可以使用new关键字来创建,有多个构造器可供使用。
下面语句使用文件名作为构造器参数来创建对象读取文件:

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

下面语句首先创建了一个File文件,然后将文件作为构造器参数来创建FileInputStream对象读取文件:

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

一旦获得了输入流对象,我们就可以通过一系列方法来读取流或做其它操作。

序号方法 & 描述
1public void close() throws IOException{}
用于关闭文件输入流。
2protected void finalize() throws IOException {}
用于清空文件的连接。
3public int read(int r) throws IOException{}
从输入流读取指定字节长度的数据。
4public int read(byte[] r) throws IOException{}
从输入流读取r.length()长度的字节到数组中。
5public int available() throws IOException{}
返回可以从输入流中读取字节的长度。

除了FileInputStream类之外,Java还提供了其它有用的类来处理输入流:

  • ByteArrayInputStream
  • DataInputStream

FileOutputStream

FileOutputStream用来将数据写入创建的文件中。如果在写入文件之前文件不存在的话,输出流会打开文件之前创建该文件。
和FileInputStream一样,FileOutputStream也可以通过下面两种方式创建对象。
首先是,使用文件名作为构造器参数来创建流对象:

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

其次是,先创建一个File文件对象,然后将File对象作为参数传入FileOutputStream流对象。

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

一旦获得了输出流对象,我们就可以通过一系列方法来将数据写入流或做其它操作。

序号方法 & 描述
1public void close() throws IOException{}
用于关闭文件输出流。
2protected void finalize() throws IOException{}
用于清空文件的连接。
3public void write(int w) throws IOException{}
将指定长度的字节写入输出流。
4public void write(byte[] w)
将w.length()长度的字节数组写入输出流。

除了FileOutputStream类之外,Java还提供了其它有用的类来处理输出流:

  • ByteArrayOutputStream
  • DataOutputStream

程序实例

下面程序展示了如何使用操作输入流和输出流。

import java.io.*;
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文件,并将给定的数字以二进制形式写入文件,控制台中输出的和文件中的内容相同。

File类和I/O

我们可以使用下面几个类来进行文件和I/O操作:

  • File类
  • FileReader类
  • FileWriter类

Java中的目录

目录本质上也是文件,是可以存放其它文件和目录的文件。我们可以使用File对象来创建目录、列出目录中的文件。有关完整的详细信息,可以查看File对象所有能调用的方法以及和目录相关的方法。

创建目录

File类提供两个很实用的方法来创建目录:

  • mkdir()方法,创建目录成功时返回true,否则返回false。创建目录失败意味着指定的路径已存在,或者目录设定的路径不完整。
  • 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);
      
      //创建目录
      d.mkdirs();
   }
}

编译上面的程序就可以创建“/tmp/user/java/bin”目录。
注意:Java按约定自动在UNIX和Windows系统上处理路径分隔符。如果在Windows系统上使用正斜杠(/),路径仍将正确解析。

列举目录

我们可以使用File对象的list()方法来列举目录中包含的所有文件和目录,如下面程序所示:

import java.io.File;
public class ReadDir {

   public static void main(String[] args) {
      File file = null;
      String[] paths;
  
      try {      
         //创建文件对象
         file = new File("/tmp");

         //文件名和目录名赋给数组
         paths = file.list();

         //遍历paths数组
         for(String path:paths) {
            //打印文件名和目录名
            System.out.println(path);
         }
      } catch (Exception e) {
         //出现错误时打印错误信息
         e.printStackTrace();
      }
   }
}

程序运行后会输出/tmp目录下的所有文件和目录:

test1.txt
test2.txt
ReadDir.java
ReadDir.class

关注公众号「小白轻松学编程」

更多交流,欢迎微信搜索并关注公众号小白轻松学编程

博客里所有教程会第一时间在公众号上更新哟,扫码关注一下吧~

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值