输出流FileOutputStream使用详解
9151字,阅读需时31分钟

前面介绍了如何应用输入流FileInputStream从本地文件读取数据。本节介绍应用输出流FileOutputStream把数据写入本地文件。

用FileOutputStream写入文件流程如下:

image.png     

                                         

图1 FileOutputStream写入文件过程

使用FileOutputStream写入文件的过程,同使用FileInputStream过程相同,都是先用File类打开本地文件,实例化输入输出流,然后调用流的读写方法写入数据,最后关闭流。

FileOutputStream的构造方法

FileOutputStream提供了4个常用构造方法,用于实例化FileOutputStream对象,不同的场景使用不同的构造方法。

场景1:使用File对象打开本地文件,从文件读取数据。

public static void main(String[] args) {
    File  file = new File("d://read.txt");
    try {
        //实例化FileOutputStream
        FileOutputStream  fos = new FileOutputStream(file);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

场景2:不使用File对象,直接传入文件路径。

public static void main(String[] args) {
    try {
        //实例化FileOutputStream
        FileOutputStream  fos = new FileOutputStream("d://read.txt");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

FileOutputStream的构造方法允许直接传入文件路径,而无须使用File对象。查看该构造方法的源代码,其内部使用了File对象打开文件。

场景3:打开文件,在文件的尾部追加写入数据。

public static void main(String[] args) {
    File  file = new File("d://read.txt");
    try {
        //实例化FileOutputStream,在文件的尾部写入数据
        FileOutputStream  fos = new FileOutputStream(file,true);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

场景要求在文件的尾部写入数据,由于前面两个构造函数都是从文件开始写入数据(覆盖原文件),因此不能使用前面2个场景的构造函数。FileOutputStream提供了另外两个构构造方法,分别是:

FileOutputStream(File file, boolean append);                   
FileOutputStream(String name, boolean append);

同前面的构造方法相比,这两个构造方法各多了一个boolean参数append。append参数为true时,数据从文件尾部写入;append参数为false时,数据覆盖原文件。

FileOutputStream的写入方法

FileOutputStream类提供了多种文件写入方法,可以单独写一个字节到文件,也可以写一个byte数组到文件,也可以取byte数组的部分数据写入到文件。

例1:使用write(int b)方法写入文件。

package com.sample;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo1 {
public static void main(String[] args) throws IOException {
    File  file = new File("d://new.txt");
    try {
        //创建文件
        file.createNewFile();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        //实例化FileOutputStream,在文件的尾部写入数据
        FileOutputStream  fos = new FileOutputStream(file);
        String  str = "this is new file";
        for( int i = 0; i < str.length();i++ )
        {
            int b = (int)str.charAt(i);
            fos.write(b);
             fos.close();
        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

例子程序首先调用File类的createNewFile()创建new.txt文件,然后将str内容写入到新创建的new.txt文件中。

例2:使用write(byte[] b)方法写入文件。

write(byte[] b)方法用于将b.length个字节从指定的byte数组写入到输出流。

package com.sample;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo2 {
public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    File  file = new File("d://new.txt");
    try {
        //创建文件
        file.createNewFile();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        //实例化FileOutputStream,在文件的尾部写入数据
        FileOutputStream  fos = new FileOutputStream(file);
        String  str = "this is new file";
        fos.write(str.getBytes());
        fos.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
 
}

String类的getBytes()方法可以将字符串转换为byte数组,使用FileOutputStream 类的write(byte[] b)方法,将转换的byte数组写入文件。

例3:使用write(byte[] b,int off,int len)方法写入文件。

该方法将len个字节的数据,并从数组b的off位置开始写入到输出流。

package com.sample;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class FileOutputStreamDemo3 {
public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    File  file = new File("d://new.txt");
    try {
        //创建文件
        file.createNewFile();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        //实例化FileOutputStream,在文件的尾部写入数据
        FileOutputStream  fos = new FileOutputStream(file);
        String  str = "this is new file";
        fos.write(str.getBytes(),5,11);
        fos.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
 
}
}

程序把指定的str内容写入到文件,fos.write(str.getBytes(),5,10)语句的第一个参数为byte数组,第二个参数5是从byte数组的下标5开始,第三个参数是写入的字节数。程序执行后,写入的内容为“is new file”。

使用该方法一定要注意数组越界的问题。例如,byte数组长度为20,从下标12开始,写入15个字节到文件,就会造成数组越界,程序报错。

例4:使用FileOutputStream复制文件

复制文件是将源文件数据写入到新文件,在实际编程中,实现文件的复制有很多种方法,本案例使用FileInputStream和FileOutputStream实现文件的复制。

package com.sample;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class FileCopyDemo {
public static void main(String[] args) throws IOException {
    String source = "d://read.txt";
    String dest = "d://newread.txt";
        File  fSource = new File(source);
        File  fDest =  new File(dest);
        //创建一个新文件
        fDest.createNewFile();
        //复制文件
        copyFile(fSource,fDest);
       
        //读取目标文件,输出文件内容
        FileInputStream fis = new FileInputStream(fDest);
     byte[] buf = new byte[fis.available()]; 
     fis.read(buf);
     //输出目标文件内容
     System.out.println("输出目标文件内容:");
     System.out.println(new String(buf)); 
 
}
public static void copyFile(File src, File dest){
        if(!src.exists()){
            System.out.println("源文件不存在");
            return ;
        }
        try {
         //创建文件输入流,读取源文件
            FileInputStream fis = new FileInputStream(src);
            //创建文件输出流,写入目标文件
            FileOutputStream fos = new FileOutputStream(dest);
 
            byte[] buf = new byte[fis.available()];
            //读取源文件
         fis.read(buf);
         //将缓冲区内的数据写入到目标文件
            fos.write(buf);
            //刷新缓冲区
            fos.flush();
 
            //关闭文件
            fos.close();
            fis.close();
            System.out.println("复制成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
 
    }
}

代码中的copyFile完成文件的复制,在复制之前,先判断一下源文件是否存在,然后申请一个byte数组,用于存储读取的源文件数据,该数组大小与源文件总字节数相同,读取成功后,再将数组内容写入到目标文件。程序输出结果如下图所示:

image.png

图 2 例4程序输出结果

文章小结

使用FileOutputStream流可以写入字节数据到目标文件,FileOutputStream提供了单字节写入和byte数组写入两种方式。建议使用byte数组写入,将待写入的数据存储到一个byte数组中,然后再写入文件。当写入的文件已经存在时,需要指明写入方式是覆盖还是追加。

我要评论
全部评论
郎宏林
授课老师
授课老师简介
项目经理,系统分析和架构师,从事多年中文信息处理技术。熟悉项目管理、擅长项目需求分析和设计、精通Java、C#、Python等编程语言。
下载APP

手机、电脑同步学

用微信或手机浏览器扫描二维码,即可下载APP。

  • 备案号:鲁ICP备15001146号
  • @1997-2018 潍坊米粒花网络技术有限公司版权所有