IO(一)----字节流

File类是文件的抽象表示,如果要对文件的内容进行读写就需要使用IO流技术。

IO流简介:(Input/Output)

    I/O类库中使用“流”这个抽象概念。Java对设备中数据的操作是通过流的方式。

    表示任何有能力产出数据的数据源对象,或者是有能力接受数据的接收端对象。“流”屏蔽了实际的I/O设备中处理数据的细节。IO流用来处理设备之间的数据传输。设备是指硬盘、内存、键盘录入、网络等。

    Java用于操作流的对象都在IO包中。IO流技术主要用来处理设备之间的数据传输。

    由于Java用于操作流的对象都在IO包中。所以使用IO流需要导包如:import java.io.*;

IO流的分类

    流按操作数据类型的不同分为两种:字节流与字符流。

    流按流向分为:输入流,输出流(以程序为参照物,输入到程序,或是从程序输出)

字节流

什么是字节流

    计算机中都是二进制数据,一个字节是8个2进制位.字节可以表示所有的数据,比如文本,音频,视频.图片,都是作为字节存在的.也就是说字节流处理的数据非常多。

在文本文件中存储的数据是以我们能读懂的方式表示的。而在二进制文件中存储的数据是用二进制形式表示的。我们是读不懂二进制文件的,因为二进制文件是为了让程序来读取而设计的。例如,Java的源程序(.java源文件)存储在文本文件中,可以使用文本编辑器阅读,但是Java的类(字节码文件)存储在二进制文件中,可以被Java虚拟机阅读。二进制文件的优势在于它的处理效率比文本文件高。

字节流处理的单元是一个字节,用于操作二进制文件(计算机中所有文件都是二进制文件)。

java中的字节流体系:输入字节流和输出字节流

字节流体系

输入字节流体系:
----| InputStream  输入字节流的基类。 抽象
----------| FileInputStream 读取文件数据的输入字节流
----------| BufferedInputStream 缓冲输入字节流    缓冲输入字节流的出现主要是为了提高读取文件数据的效率。其实该类内部只不过是维护了一个8kb的字节数组而已。

输出字节流体系
--------| OutputStream  所有输出字节流的基类  抽象类
------------| FileOutputStream 向文件输出数据的输出字节流
------------| Bufferedoutputstream  缓冲输出字节流    BufferedOutputStream出现的目的是为了提高写数据的效率。 内部也是维护了一个8kb的字节数组而已。

注意:判断使用输入流还是输出流的依据是:以内存为参考物,数据进入内存使用input,数据出内存用output。

输入字节流

文件输入字节流文件:FileInputStream

步骤:

  1. 找到目标文件
    2. 建立数据的输入通道。
    3. 读取文件中的数据。
    4. 关闭资源.

常用方法:
1、构造方法:

FileInputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。

FileInputStream(String name) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

2、读取方法:

int read() 从此输入流中读取一个数据字节。返回读取的字节数据,如果到了文件末尾则返回-1

int read(byte[] b)  从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。返回读入缓冲区的字节数,如果到了文件末尾返回-1;

3、关闭资源方法:

void close() 关闭此文件输入流并释放与此流有关的所有系统资源。

代码示例:

 1 public static void readFile(String fileName){
 2         File file = null;
 3         FileInputStream fileInputStream = null;
 4         try {
 5             file = new File("E:\nick.txt");
 6             fileInputStream = new FileInputStream(file);
 7             byte[] buf = new byte[1024]; //数组的大小一般为1024的倍数
 8             int count = 0;
 9             while((count = fileInputStream.read(buf))!= -1){
10                 System.out.println(new String(buf, 0, count));
11             }
12         }catch(IOException e){
13             System.out.println("文件读取错误");
14             throw new RuntimeException(e);
15         } finally {
16             try {
17                 if (fileInputStream != null ) {
18                     fileInputStream.close();
19                 }
20             } catch (IOException e) {
21                 System.out.println("关闭文件失败");
22                 throw new RuntimeException(e);
23             }
24         }
25     }
View Code

缓冲输入字节流BufferedInputStream

此类的目的是提高程序读取文件的效率。实现原理是内部维护了一个8KB的byte数组,读取的时候会一次读取满数组的字节,然后在对内存中的数组进行操作,从而来提高效率。

使用步骤:

  1. 找到目标文件。
    2. 建立数据的输入通道。
    3. 建立缓冲输入字节流。
    4. 读取文件中的数据。
    5. 关闭文件。

常用方法:1、构造方法:

BufferedInputStream(InputStream in)  创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。

2、读取方法:

int read() 从此输入流中读取一个数据字节。

int  read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。

3、关闭资源方法:

void close() 关闭此文件输入流并释放与此流有关的所有系统资源。

代码示例:

 1 import java.io.BufferedInputStream;
 2 import java.io.File;
 3 import java.io.FileInputStream;
 4 import java.io.IOException;
 5 
 6 public class FileStream {
 7     public static void main(String[] args){
 8         ReadFile2();
 9     }
10 
11     public static void ReadFile2() {
12         File file = null;
13         FileInputStream fileInputStream = null;
14         BufferedInputStream bufferedInputStream = null;
15         try {
16             file = new File("E:\nick.txt");
17             fileInputStream = new FileInputStream(file);
18             bufferedInputStream = new BufferedInputStream(fileInputStream);
19             int content = 0;
20             while((content = bufferedInputStream.read())!=-1){
21                 System.out.print((char)content);
22             }
23         } catch (IOException e) {
24             System.out.println("读取文件失败");
25             throw new RuntimeException(e);
26         }finally {
27             if (fileInputStream != null) {
28                 try {
29                     bufferedInputStream.close();
30                 } catch (IOException e) {
31                     System.out.println("关闭文件失败");
32                     throw new RuntimeException(e);
33                 }
34             }
35         }
36     }
37 }
View Code

输出字节流

文件字节输出流:FileOutputStream

步骤:

  1. 找到目标文件
    2. 建立数据的输出通道。
    3. 把数据转换成字节数组写出。
    4. 关闭资源

常用方法:

1、构造方法

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

FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。当append为true时,续写文件。当apend为false时,重写文件。

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

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

2、写入方法:

void write(byte[] b)b.length 个字节从指定 byte 数组写入此文件输出流中。

void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

void  write(int b) 将指定字节写入此文件输出流。

3、关闭资源:

void close() 关闭此文件输出流并释放与此流有关的所有系统资源。

代码示例:

 1 public static void writeFile(){
 2         FileOutputStream fileOutputStream = null;
 3         try{
 4             File file = new File("E:\nick.txt");
 5             fileOutputStream = new FileOutputStream(file,true);
 6             String string = "abc";
 7             fileOutputStream.write(string.getBytes());
 8             System.out.println("写入文件成功");
 9         }catch(IOException e){
10             System.out.println("写入文件出错");
11             throw new RuntimeException(e);
12         }finally {
13             try {
14                 if (fileOutputStream != null) {
15                     fileOutputStream.close();
16                 }
17             } catch (IOException e) {
18                 System.out.println("关闭资源文件失败");
19                 throw new RuntimeException(e);
20             }
21         }    
22     }
View Code

注意事项:

  1. 使用FileOutputStream 的时候,如果目标文件不存在,那么会自动创建目标文件对象。 如果在目录不存在就会抛异常。
    2. 使用FileOutputStream写数据的时候,如果目标文件已经存在,那么会先清空目标文件中的数据,然后再写入数据。
    3.使用FileOutputStream写数据的时候, 如果目标文件已经存在,需要在原来数据基础上追加数据的时候应该使用new FileOutputStream(file,true)构造函数,第二参数为true。
    4.使用FileOutputStream的write()方法写数据的时候,虽然接收的是一个int类型的数据,但是真正写出的只是一个字节的数据,只是把低八位的二进制数据写出,其他二十四位数据全部丢弃。

缓冲输出字节流

此类类似于BufferedInputStream,在内部也维护了一个8KB的byte数组。从而来提高文件写入的效率。

步骤:

  1. 找到目标文件。
    2. 建立数据的输入通道。
    3. 建立缓冲输入字节流。
    4. 写入文件。
    5. 关闭文件。

常用方法

1、构造方法:

BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

2、写入方法:

void write(int b) 将指定的字节写入此缓冲的输出流。

void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。

void  flush() 刷新此缓冲的输出流。

3、关闭资源:

void close() 关闭此文件输出流并释放与此流有关的所有系统资源。

代码示例:

 1 public static void writeFile2() {
 2         File file = null;
 3         FileOutputStream fileOutputStream = null;
 4         BufferedOutputStream bufferedOutputStream = null;
 5         try {
 6             file = new File("E:\nick.txt");
 7             fileOutputStream = new FileOutputStream(file,true);
 8             bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
 9             String string = "hello world";
10             bufferedOutputStream.write(string.getBytes());
11             bufferedOutputStream.flush();
12             System.out.println("写入文件成功");
13         } catch (Exception e) {
14             System.out.println("写入文件失败");
15             throw new RuntimeException(e);
16         }finally {
17             if (fileOutputStream != null) {
18                 try {
19                     bufferedOutputStream.close();
20                 } catch (IOException e) {
21                     System.out.println("关闭资源文件失败");
22                     throw new RuntimeException(e);
23                 }
24             }
25         }
26     }
View Code

注意事项:

   1. 使用BufferedOutStream写数据的时候,它的write方法是是先把数据写到它内部维护的字节数组中。
     2. 使用BufferedOutStream写数据的时候,它的write方法是是先把数据写到它内部维护的字节数组中,如果需要把数据真正的写到硬盘上面,需要调用flush方法或者是close方法、 或者是内部维护的字节数组已经填满数据的时候。

  3.BufferedOutStream写入文件的时候是续写文件,并不清空原有文件中的数据。

实战

需求:拷贝图片。

代码示例如下:

 1 public static void copyImage(){
 2         FileInputStream fileInputStream = null;
 3         FileOutputStream fileOutputStream = null;
 4         try {
 5             File infile = new File("E:\Image\IMG_1885.JPG");
 6             File outfile = new File("E:\nick.jpg");
 7             fileInputStream = new FileInputStream(infile);
 8             fileOutputStream = new FileOutputStream(outfile);
 9             byte[] buf = new byte[1024];
10             int count = 0;
11             while((count = fileInputStream.read(buf)) != -1){
12                 fileOutputStream.write(buf, 0, count);
13             }
14         } catch (IOException e) {
15             System.out.println("复制图片失败");
16             throw new RuntimeException(e);
17         }finally{
18             if (fileOutputStream != null) {
19                 try {
20                     fileOutputStream.close();
21                 } catch (IOException e) {
22                     System.out.println("关闭输出流失败");
23                     throw new RuntimeException(e);
24                 }finally {
25                     if (fileInputStream != null) {
26                         try {
27                             fileInputStream.close();
28                         } catch (IOException e) {
29                             System.out.println("关闭输入流失败");
30                             throw new RuntimeException(e);
31                         }
32                     }
33                 }
34             }
35         }
36     }
View Code

注意:

文件操作中对于资源的开启和关闭的原则:先开后关,后开先关。

原文地址:https://www.cnblogs.com/nicker/p/6248531.html