一、FileOutputStream

  1、FileOutputStream 类概述

    java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件,是 OutputStream 最简单的一个子类。

     FileOutputStream 类是用于字节的输出流。

  2、FileOutputStream 类继承结构

    

 

  3、构造方法

 FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。
 FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

  

   参数:写入数据的目的地。

      String name:目的地是一个文件的路径。

      File file:目的地是一个文件。

    构造方法的作用

      ① 创建一个 FileOutputStream 对象

      ② 会根据构造方法中传递的文件/文件路径,创建一个空的文件

      ③ 会把 FileOutputStream 对象指向创建好的文件 

   写入数据的原理:

    java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据写入到文件中

   字节输出流的使用步骤【重要】:

     ① 创建一个FileOutputStream对象,构造方法中传递写入数据的目的地

     ② 调用FileOutputStream对象中的方法write,把数据写入到文件中

     ③ 释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)

 

二、常用方法

 

void write(int b)

    将指定的字节写入此输出流。 write 的常规协定是:向输出流写入一个字节。 要写入的字节是参数 的八个低位。 的 24 个高位将被忽略。 即写入0~255范围的。

void write(byte[] b)

    将 b.length 个字节从指定的 byte 数组写入此输出流。 write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同。

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

    将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

public void flush()throws IOException

    刷新此输出流并强制写出所有缓冲的输出字节, 调用此方法指示应将这些字节立即写入它们预期的目标。

public void close() throws IOException

    关闭此输出流并释放与该流关联的所有系统资源。

三、案例

  1、写出字节

    使用write(int b) 方法,每次可以写出一个字节数据,代码使用演示:

1     public static void main(String[] args) throws IOException {
2         //1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
3         FileOutputStream fos = new FileOutputStream("E:\\a.txt");
4         //2.调用FileOutputStream对象中的方法write,把数据写入到文件中
5         //public abstract void write(int b) :将指定的字节输出流。
6         fos.write(97);
7         //3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
8         //fos.close();
9     }

 

      原理:

 

  2、写出字节数组

    使用write(byte[] b) ,每次可以写出数组中的数据,代码使用演示:

 1 public static void main(String[] args) throws IOException {
 2         //创建FileOutputStream对象,构造方法中绑定要写入数据的目的地
 3         FileOutputStream fos = new FileOutputStream(new File("E:\\b.txt"));
 4         //调用FileOutputStream对象中的方法write,把数据写入到文件
 5 
 6         /*
 7             public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。
 8             一次写多个字节:
 9                 如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
10                 如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
11          */
12         byte[] bytes = {65,66,67,68,69};//ABCDE
13         //byte[] bytes = {-65,-66,-67,68,69};//烤紻E
14         fos.write(bytes);
15 
16         /*
17             写入字符的方法:可以使用String类中的方法把字符串,转换为字节数组
18                 byte[] getBytes()  把字符串转换为字节数组
19          */
20         byte[] bytes2 = "你好".getBytes();
21         System.out.println(Arrays.toString(bytes2));//[-28, -67, -96, -27, -91, -67]
22         fos.write(bytes2);
23 
24         //释放资源
25         fos.close();
26     }

 

  3、写出指定长度字节数组

    write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节,代码使用演示:

 1    public static void main(String[] args) throws IOException {
 2         //创建FileOutputStream对象,构造方法中绑定要写入数据的目的地
 3         FileOutputStream fos = new FileOutputStream(new File("09_IOAndProperties\\b.txt"));
 4 
 5         /*
 6             public void write(byte[] b, int off, int len) :把字节数组的一部分写入到文件中
 7                 int off:数组的开始索引
 8                 int len:写几个字节
 9          */
10         byte[] bytes = {65,66,67,68,69};//ABCDE
11         fos.write(bytes,1,2);  //BC
12 
13         //释放资源
14         fos.close();
15     }

 

  4、数据追加续写

    追加写/续写:使用两个参数的构造方法

FileOutputStream(String name, boolean append)创建一个向具有指定 name 的文件中写入数据的输出文件流。
FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

 

    参数

      String name,File file:表示写入数据的目的地。

      boolean append :是否开启追加

          true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据

          false:创建一个新文件,覆盖源文件;

    Demo:

1 public static void main(String[] args) throws IOException {
2         FileOutputStream fos = new FileOutputStream("E:\\c.txt",true);
3         for (int i = 1; i <=10 ; i++) {
4             fos.write("你好".getBytes());
5         }
6 
7         fos.close();
8     }

 

  5、写出换行

    可以发现写出的内容到文件内都是在一行内显示,没有换行。

    回车符 \r 和换行符 \n

回车符:回到下一行开头(return)
换行符:下一行(newline)

     写换行:需要写换行符号。

    

    系统中的换行

Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
Linux / Unix系统里,每行结尾只有 换行 ,即 \n ;
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一

    Demo:

1   public static void main(String[] args) throws IOException {
2         FileOutputStream fos = new FileOutputStream("E:\\c.txt",true);
3         for (int i = 1; i <=10 ; i++) {
4             fos.write("你好".getBytes());
5             fos.write("\r\n".getBytes());
6         }
7 
8         fos.close();
9     }

 

四、应用案例

  1、实现对图片的复制操作

 1     @Test
 2     public void testFileInputOutputStream()  {
 3         FileInputStream fis = null;
 4         FileOutputStream fos = null;
 5         try {
 6 
 7             File srcFile = new File("a.jpg");
 8             File destFile = new File("b.jpg");
 9 
10 
11             fis = new FileInputStream(srcFile);
12             fos = new FileOutputStream(destFile);
13 
14             //复制的过程
15             byte[] buffer = new byte[5];
16             int len;
17             while((len = fis.read(buffer)) != -1){
18                 fos.write(buffer,0,len);
19             }
20 
21         } catch (IOException e) {
22             e.printStackTrace();
23         } finally {
24             if(fos != null){
25                 //
26                 try {
27                     fos.close();
28                 } catch (IOException e) {
29                     e.printStackTrace();
30                 }
31             }
32             if(fis != null){
33                 try {
34                     fis.close();
35                 } catch (IOException e) {
36                     e.printStackTrace();
37                 }
38 
39             }
40         }
41 
42     }

 

  2、指定路径下文件的复制

    实现:

 1     public void copyFile(String srcPath,String destPath){
 2         FileInputStream fis = null;
 3         FileOutputStream fos = null;
 4         try {
 5 
 6             File srcFile = new File(srcPath);
 7             File destFile = new File(destPath);
 8 
 9             fis = new FileInputStream(srcFile);
10             fos = new FileOutputStream(destFile);
11 
12             //复制的过程
13             byte[] buffer = new byte[1024];
14             int len;
15             while((len = fis.read(buffer)) != -1){
16                 fos.write(buffer,0,len);
17             }
18 
19         } catch (IOException e) {
20             e.printStackTrace();
21         } finally {
22             if(fos != null){
23                 //
24                 try {
25                     fos.close();
26                 } catch (IOException e) {
27                     e.printStackTrace();
28                 }
29             }
30             if(fis != null){
31                 try {
32                     fis.close();
33                 } catch (IOException e) {
34                     e.printStackTrace();
35                 }
36 
37             }
38         }
39     }

 

    注意:在这里指定的字节数组,不应该太大或太小,一般为 1024 或为 1024 的整数倍。

  3、用上面的方法测试复制视频

    代码实现:

 1     @Test
 2     public void testCopyFile(){
 3 
 4         long start = System.currentTimeMillis();
 5 
 6         String srcPath = "C:\\Users\\Administrator\\Desktop\\01-视频.avi";
 7         String destPath = "C:\\Users\\Administrator\\Desktop\\02-视频.avi";
 8 
 9 
10         //String srcPath = "hello.txt";
11         //String destPath = "hello3.txt";
12 
13         copyFile(srcPath,destPath);
14 
15 
16         long end = System.currentTimeMillis();
17 
18         System.out.println("复制操作花费的时间为:" + (end - start));//618
19 
20     }

 

    可以发现基于字节流的传输,来对于来说传输效率还是不错的。

    而且字节流不仅仅可以用于非字符文件,还可以适用于字符文件的传输。    

 

五、注意点

  1、写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖;

  2、如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容;

  3、字节流操作字节,比如: .mp3.avi.rmvbmp4.jpg.doc.ppt;

 

posted on 2021-06-01 13:58  格物致知_Tony  阅读(556)  评论(0编辑  收藏  举报