**
**
File类不支持文件内容处理,如果要处理文件内容,必须要通过流的操作模式来完成。流分为输入流和输出流。
在java.io包中,流分为两种:字节流与字符流
I.字节(byte)流:InputStream、OutputStream,可以处理文本文件、图像、音乐、视频等资源。
II.字符(char)流:Reader、Writer,只能用于处理中文文本。
字节流与字符流的本质区别只有一个:字节流是原生的操作,而字符流是经过处理后的操作。(处理就是经过转换流操作之后的结果)
在进行网络数据传输、磁盘数据保存所支持的数据类型只有:字节。
而所有磁盘中的数据必须先读取到内存后才能进行操作,而内存会帮助我们把字节变成字符。字符更容易处理中文。
不管使用的是字节流还是字符流,其基本的操作流程几乎一样,以文件操作为例。
1. 取得终端对象–根据文件路径创建File类对象;
2. 根据终端对象取得输入输出流–根据字节流或者字符流的子类实例化父类对象;
3. 根据输入输出流进行数据的读取或写入操作
4. 关闭流(close())。
对于IO操作属于资源处理,所有的资源处理操作(IO操作、数据库操作、网络)最后必须要进行关闭。
OutputStream类的定义结构:
public abstract class OutputStream implements Closeable, Flushable
只要有一个OutputStream对象,就可以调用OutputStream类中的方法,
I.OutputStream类实现了Closeable和Flushable两个接口,这两个接口中的方法:
1. Closeable: public void close() throws IOException;关闭流方法
2. Flushable: public void flush() throws IOException;刷新缓冲区
II.在OutputStream类中的核心方法:
1). 将给定的字节数组内容全部输出:
public void write(byte b[]) throws IOException
2). 将给定的字节数组以off位置开始输出len长度后停止输出内:
public void write(byte b[], int off, int len) throws IOException
3). 输出单个字节:
public abstract void write(int b) throws IOException;
III.由于OutputStream是一个抽象类,所以要想为父类实例化,必须要使用子类FileOutputStream类来处理,使用如下的两种构造方法:
1). 接收File类(覆盖):
public FileOutputStream(File file) throws FileNotFoundException
2). 接收File类(追加):
public FileOutputStream(File file, boolean append)
使用OutputStream输出数据时,若指定的文件不存在,FileOutputStream会自动创建文件(不包含创建目录)
IV.AutoCloseable自动关闭支持
从jdk1.7开始追加了一个AutoCloseable自动关闭接口,这个接口的主要没目的是自动进行关闭处理,但是这种处理一般不好用,因为使用它必须结合try…catch。推荐使用显示关闭.
public abstract class InputStream implements Closeable
将读取的内容放入字节数组中:public int read(byte b[]) throws IOException
返回值有以下三种情况:
I.返回b.length:未读取的数据>存放的缓存区大小,返回字节数组大小;
II.返回大于0的整数,此整数小于b.length:未读取的数据<存放区大小,返回剩余数据大小;
III.返回-1:表示此时数据已经读取完毕。
字符适合于处理中文数据,Writer是字符输出流的处理类,这个类的定义如下:
public abstract class Writer implements Appendable, Closeable, Flushable
在Writer类中提供write()方法,而且该方法接受的类型都是char型,
Writer类提供了一个直接输出字符串的方法:
public void write(String str) throws IOException
字符流若未关闭,数据在缓存区存放,不会输出到目标终端。要想将数据输出,要么将输出流关闭要么使用flush()强制刷新缓存区
public int read(char cbuf[])throws Exception
Reader依然是一个抽象类。如果要进行文件读取,需要使用FileReader。
Writer类提供了write()方法直接输出字符串,而在Reader类中没有方法可以直接读取字符串类型,此时只能通过字符数组进行读取操作。
OutputStreamWriter类(字节输出流->字符输出流)是Writer类的子类
继承关系:public class OutputStreamWriter extends Writer
构造方法:public OutputStreamWriter(OutputStream out)
InputStreamReader(字节输入流->字符输入流)是Reader类的子类
继承关系:public class InputStreamReader extends Reader
构造方法:public InputStreamReader(InputStream in)
字符流的具体子类大都是通过转换流将字节流转为字符流(FileWriter继承转换流)
创建一个CopyFile类,这个类通过初始化参数接收源文件与目标文件路径。
package javaSE.bit.file;
import java.io.*;
/**
* 文件拷贝
* @author mayanni
* @date 2019-05-05 14:20
*/
public class TestCopyFile {
public static void main(String[] args)throws Exception {
//源文件路径
String sourceFilePath="D:"+File.separator+"JavaSE code"+File.separator
+"test"+File.separator+"4.jpg";
//目标文件路径
String destFilePath="D:"+File.separator+"JavaSE code"+File.separator
+"test"+File.separator+"鸭子.jpg";
copyFile(sourceFilePath,destFilePath);
}
public static void copyFile(String sourceFilePath,
String destFilePath) throws Exception{
//1.取得源文件与目标文件的File对象
File sourceFile=new File(sourceFilePath);
File destFile=new File(destFilePath);
//2.取得输入输出流,
// 将源文件的内容读取到程序中,再将程序中的内容输出到目标文件中
InputStream in=new FileInputStream(sourceFile);
OutputStream out=new FileOutputStream(destFile);
//3.数据输入输出
int len =0;
byte[] data=new byte[1024];//开辟1k的缓存区,一次性读入多个内容
long start =System.currentTimeMillis();
while((len=in.read(data))!=-1){
out.write(data,0,len);
}
long end=System.currentTimeMillis();
System.out.println("共耗时"+(end-start)+"毫秒");
}
}