Java 写文件:FileOutputStream


 

[简介]:

无论是二进制数据还是字符数据(文本数据)都可以用文件输出流 java.io.FileOutputStream 以字节流的方式保存到所指定文件。不过,如果写字符数据,FileWriter 更方便一些。FileWriter 除了提供了文件写入功能之外,还内置了字符编码功能。(关于 FileWriter 的使用,请参考本站相关文章)

java.io.FileOutputStream  类继承和重写了抽象类 java.io.OutputStream。他们两个都是从最早的JDK, JDK1.0就已经存在的类。


[父类 OutputStream]

抽象类 OutputStream 是所有字节输出流的基类,它共定义了一个构造方法和五个方法。构造方法什么也没做。在五个方法中,有,

  • 三个 Write 方法:

public abstract void write(int b) throws IOException

向输出流里写入一个值为 b 的字节。需要注意的是,实际写入的是 int 类型 b 的低8位,其余的 24 位被忽略。
如果有错误,则抛出 IOException。调用这个方法时,需要捕获和处理 IOException。这个方法是OutputStream 类的唯一的抽象方法,需要具体类必须实现。一般的例程为参看下面示例程序。

public void write(byte[] b) throws IOException

向输入流里写入一个字节数组b。效果和 write(b, 0, b.length) 相同。调用这个方法时,需要捕获和处理 IOException。OutputStream 和 FileOutputStream 的实现都是调用了下面的方法。

public void write(byte[] b, int off, int len) throws IOException 

把位置为 off、长度为len 的字节数组b中的数据写入到输出流中。OutputStream 的实现是反复调用write(int b), 子类应该提供更有效率的实现。如果 b 是 null, 则抛出NullPointerException 。如果off 或者 len 小于0,或者 off + len 大于数组 b 的长度, 则抛出 IndexOutOfBoundsException 。
FileOutputStream  重写了这个方法。

 

下面用一段例程演示 void write(int b) 和 void write(byte[] b) 的使用:

 

// TestFileOutputStream.java

 

import java.io.*;

public class TestFileOutputStream
{
 
  public static void testWrite()
  {
    try{
      FileOutputStream fo = new FileOutputStream("MyOut.dat");
     
      fo.write(0);
      fo.write(0x43);
      fo.write(0x44);
      //fo.flush(); // 如果OutputStream 的实现使用了缓存,这个方法用于清空缓存里的数据,并通知底层去进行实际的写操作
                    // FileOutputStream 没有使用缓存,因此这个方法调用与否在这个例子的运行结果没有影响。

      fo.close();   // 注意:如果用户忘记关闭打开的文件,系统可以通过 finalyze 方法在垃圾回收的时候替用户关闭这个流。
                    // 虽然如此,用户应该显示的调用这个方法。
    }catch(IOException e)
    {
      e.printStackTrace();
    }
  }
 
 
  public static void testWriteBytes()
  {
    try{
     // 构造一个要写的数据:
      byte[] data = "这个例子测试文件写".getBytes("GB2312");
      
      FileOutputStream fo = new FileOutputStream("MyOut1.data");
      fo.write(data);
      //fo.flush();      //如果OutputStream 的实现使用了缓存,这个方法用于清空缓存里的数据,并通知底层去进行实际的写操作
                         // FileOutputStream 没有使用缓存,因此这个方法调用与否在这个例子的运行结果没有影响。
      fo.close();     
     
    }catch(Exception e)
    {
      e.printStackTrace();
    }
  }
 
  public static void main(String[]args)
  {

    testWrite();
    testWriteBytes();
  }
}

 

  • 其余两个方法

public void flush() throws IOException
如果OutputStream 的实现使用了缓存,这个方法用于清空缓存里的数据,并通知底层去进行实际的写操作。需要注意的是,这个缓存特指Java层的缓存。这个方法对底层(如操作系统)的缓存不起作用。参见 FileDescriptor。

OutputStream 中这个方法的实现什么也没做。具体子类应该重写这个方法。FileOutputStream 没有使用缓存,因此没有重写这个方法。因此,上面代码示例中,这个方法调用与否对运行结果没有影响。

 

public void close() throws IOException

这个方法用于关闭流。虽然,如果用户忘记调用这个方法,系统可以通过 finalyze 方法在 OutputStream 对象垃圾回收的时候替用户关闭这个流。但用户应该养成良好的习惯显示的调用这个方法!

OutputStream 中这个方法的实现什么也没做。具体子类应该重写这个方法。java.io.FileOutputStream 重写了这个方法。 用于真正关闭相应的文件资源。

 

[FileOutputStream 的其他方法]: 

java.io.FileOutputStream 除了重写 OutputStream 中上述四个方法之外,还提供了额外三个方法:

 

protected void finalize() throws IOException 。这个方法其实是重写了 Object 中的这个方法(Object 是所有Java 类(包括数组类型)的“根级”父类)。这个方法是被 Java 虚拟机中的垃圾回收器调用的。用于 Java 对象已经不存在了但它占有的资源没有释放的情况。FileOutputStream 实现中,这个方法主要是调用了 close() 方法。上面例子中,如果用户没有调用 close() 方法,系统就通过这个方法在垃圾回收的时候关闭文件。但写程序时应该养成显示关闭文件的习惯。

 

public final FileDescriptor getFD() throws IOException。 这个方法返回 FileDescriptor  对象,这个对象表示这个文件流对应的文件系统中的实际文件。

关于 FD 的使用,请参见本站相关文章。

 

public FileChannel getChannel() 这是在 JDK1.4 中引入的方法。用于支持New IO 的特性。这个方法返回 FileChannel 对象,这个对象表示这个文件对应的文件系统中的通道。关于Channel 和 New IO,请参阅本站其它文章。

 

[关于 FileOutputStream 的构造]

FileOutputStream 提供了五个构造方法:

FileOutputStream(File file) throws FileNotFoundException  和 FileOutputStream(String name) throws FileNotFoundException 都是通过实际文件路径(或其标识的File对象)来创建文件流。需要注意的是,如果文件不存在,(待查:是否会创建文件)。如果文件存在,则这两个构造方法中有打开文件的操作。如果文件给定的是目录而不是文件,或者文件不存在又不能创建,或者文件存在却不能打开,则抛出 FileNotFoundException 异常。如果文件由于安全保护而不允许读取,则抛出 SecurityException 异常。

 

写文件需要考虑的一个问题是,是从文件头写入(覆盖原有数据),还是从文件尾写入(增加数据)。上面的两个构造方法都是按照前者实现的,针对后者的情况,FileOutputStream 提供另外两个构造方法:

FileOutputStream(File file, boolean append) throws FileNotFoundException  FileOutputStream(String name, boolean appendthrows FileNotFoundException 

这两个构造方法多了一个 append 参数,如果参数值是 true, 则是“增加数据”,如果参数值是 false, 则是“覆盖原有数据”。即,退化成前两种构造方法。

 

最后,同 FileInputStream 一样, FileOutputStream 提供了用已经打开的文件来创建一个新的文件流:

public FileInputStream(FileDescriptor fdObj) 这个构造方法里没有打开文件操作。输入的 FD 对应的一定是一个已经打开的文件。


[声明]:联系方式: yixiaoqiang@gmail.com

本文博主(gulibia):http://blog.sina.com.cn/s/blog_66e177dd0100hf92.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值