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 }
缓冲输入字节流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 }
输出字节流
文件字节输出流: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 }
注意事项:
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 }
注意事项:
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 }
注意:
文件操作中对于资源的开启和关闭的原则:先开后关,后开先关。