总结:
File 类 仅能获取文件的属性数据或者是修改文件的属性数据而已,不能读取文件内容数据。
如果需要操作文件内容数据,那么就需要学习”IO流”技术
IO流类别:
1. 流向划分
输入流
输出流
什么时候使用输入流什么时候使用输出流?
以当前程序作为参照物,数据流入 则使用输入流, 数据流出则使用输出流。
输入字节流:
———|InputStream 抽象类 输入字节流的基类。
————| FileInputStream 读取文件数据 的输入字节流
使用FileInputStream 读取文件数据步骤:
找到目标文件
建立数据的输入通道
public static void read() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据的通道
FileInputStream fileInputStream= new FileInputStream(file);
//读取数据
byte[] buf = new byte[1024]; //缓冲字节数组的长度一般都是1024的倍数。 缓冲字节数组一般越大效率越高
int length = 0 ; //记录本次读取的自己个数。
while((length = fileInputStream.read(buf))!=-1){
System.out.print(new String(buf,0,length));
}
//关闭资源(释放资源文件)
fileInputStream.close();
}
输出字节流:
——–| OutputStream 抽象类,所有输出字节字节流的父类。
————| FileOutputStream 向文件输出数据的输出字节流。
使用FileOutputStream步骤:
1. 找到目标文件
2. 建立数据的输出通道
3. 准备数据,把数据写出
4. 把字符串转成字节数组
5. 字节数组写出
6. 关闭资源
FileOutputStream要注意的细节:
1. new FileOutputStream 的时候,如果目标文件不存在,那么会先创建目标 文件,然后再写入。
2. new FileOutputStream(file) 如果目标文件已经存在,那么会先清空 目标文件的数据,然后再写入新的数据.
3. 写入数据的时候如果需要以追加的形式写入,那么需要使用new FileOutputStream(file,true) 这个构造函数。
4. 使用write(int b)方法的时候,虽然参数接受的一个int类型的数据,但是实际上只会把数据的低八位写出,其他24位丢弃。
00000000-00000000-00000001-10000000
write(byte[] b, int off, int len)
//方式一: 先把数据转成字节数组然后再写出。
public static void write1() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file,true); //第二个参数为true时,写入文件数据就是以追加的形式写入的
//准备数据, 把数据写出
String str = "\r\nhello world";
//把字符串转成字节数组
byte[] buf = str.getBytes();
//把字节数组写出
fileOutputStream.write(buf);
//关闭资源
fileOutputStream.close();
}
//方式二
public static void write2() throws IOException {
// 找到目标文件
File file = new File("F:\\a.txt");
// 建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
String data = "abcd";
byte[] buf = data.getBytes(); // 97 98 99 100
fileOutputStream.write(buf, 0, 2); // 指定开始的索引值与字节个数写出。
fileOutputStream.close();
}
//方式三: 每次只能写 一个字节的数据 。
public static void write3() throws IOException{
//找到目标文件
File file = new File("f:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//把数据写出
fileOutputStream.write('h');
fileOutputStream.write('e');
fileOutputStream.write('l');
fileOutputStream.write('l');
fileOutputStream.write('o');
//关闭资源
fileOutputStream.close();
}
/*
4. 使用write(int b)方法的时候,虽然参数接受的一个int类型的数据,但是实际上只会把数据的低八位写出,其他24位丢弃。
00000000-00000000-00000001-10000000
*/
public static void writeTest() throws FileNotFoundException, IOException {
File file = new File("F:\\b.txt");
//建立数据输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//把数据写出
fileOutputStream.write(384);
//关闭资源
fileOutputStream.close();
}
File inFile = new File("F:\\美女\\1.mp3");
File outFile = new File("E:\\拷贝.mp3");
//建立数据通道
FileInputStream fileInputStream = new FileInputStream(inFile);
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
//建立缓冲字节数组,边读边写
byte[] buf = new byte[1024];
int length = 0 ; //用于记录每次读取的字节个数
while((length=fileInputStream.read(buf))!=-1){ // 700 300
fileOutputStream.write(buf,0,length);
}
//关闭资源(关闭资源的原则:先开后关,后开先关)
fileOutputStream.close();
fileInputStream.close();
//拷贝图片
public static void copyImage(){
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try{
//找到目标文件
File inFile = new File("F:\\美女\\1.jpg");
File outFile = new File("F:\\拷贝.jpg");
//建立数据的输入输出通道
fileInputStream = new FileInputStream(inFile);
fileOutputStream = new FileOutputStream(outFile);
//建立缓冲字节数组,边读边写
byte[] buf = new byte[1024];
int length = 0 ;
while((length = fileInputStream.read(buf))!=-1){
fileOutputStream.write(buf,0,length);
}
}catch(IOException e){
System.out.println("拷贝出错了...");
throw new RuntimeException(e);
//关闭资源的原则: 先开后关, 后开先关。
}finally{
try{
if(fileOutputStream!=null){
//关闭资源
fileOutputStream.close();
}
}catch(IOException e){
throw new RuntimeException(e);
}finally{
try{
if(fileInputStream!=null){
fileInputStream.close();
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
}
}
使用FileInputStream读取文件数据的时候如何读取效率是最高?
使用字节数组作为缓冲区读取的效率是最高的。
我们知道使用缓冲字节数组读取文件的效率最高,sun也知道使用缓冲字节数组读取的效率高,这时候sun为了方便我们工作,编写一个缓冲输入字节流给我去使用。
缓冲输入字节流的作用: 提高我们读取文件数据的效率。
输入字节流的体系:
———-| InputStream 抽象类 所有输入字节流的基类
————–| FileInputStream 读取文件数据的输入字节流
————–|BufferedInputStream 缓冲输入字节流 该类的本质其实只是在内部维护了一个8kb的字节数组而已。 主要是为了提高我们的读取文件 的效率。
凡是缓冲流都没有读写文件的能力。
BuffereInputStream注意的事项:
1. BuffereInputStream 的close方法实际上关闭的就是你传递进去的FileInputStream对象。
public static void readTest() throws IOException {
//第一步:找到目标文件
File file = new File("F:\\a.txt");
//第二步:建立文件与程序的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
//第三部:建立缓冲输入字节流
/*
疑问: 为什么创建BufferedInputStream对象需要传入一个InputStream的对象呢?
BufferedInputStream没有读取文件 数据的能力,但是又要读取文件的数据,这时候只能依赖一个具备
读取文件数据能力的对象。
*/
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//读取文件数据
int content = 0;
/*
疑问: BufferedInputStream 的read方法每次只是读取一个字节的数据,FileInputStream的read方法每次也是读取一个字节的数据
那么为什么说BufferedInputStream提高了读取的效率呢?
InputStream流是指将字节序列从外设或外存传递到应用程序的流
BufferedInputStream流是指读取数据时,数据首先保存进入缓冲区,其后的操作直接在缓冲区中完成。
*/
while((content = bufferedInputStream.read())!=-1){
System.out.print((char)content);
}
//关闭资源 实际上关的是inputStream 的close方法
bufferedInputStream.close();
} 这里写代码片
缓冲输出字节流: 为了提高写文件的效率。
———| OutputStream 抽象类, 所有输出字节流的基类。
————-| FileOutputStream 向文件写出数据的输出字节流对象。
————-| BufferedOutputStream 缓冲输出字节流, 为了提高写文件数据的效率。
BufferedOutputStream 需要注意的事项: BufferedInputStream
1. 使用BufferedOutputStream的write方法时候,数据其实是写入了BufferedOutputStream内部维护的字节数组中,只有你调用BufferedOutputStream的close方法或者是flush方法数据才会真正的写到硬盘上去或者内部维护的字节数组已经存储满数据了,这时候 数据才会写到硬盘上去。
2/. BufferedOutputStream 的close方法实际上关闭的就是你传入的OutputStream对象的close方法。
//找到目标文件对象
File file = new File("f:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//建立缓冲输出字节流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//写数据
String data = "hello world";
bufferedOutputStream.write(data.getBytes());
// bufferedOutputStream.flush(); //把缓冲字节数组的数据写到硬盘上去。
bufferedOutputStream.close();
public class CopyImage {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
//找到目标文件
File inFile = new File("F:\\美女\\1.jpg");
File outFile = new File("E:\\拷贝.jpg");
//建立数据的输入输出通道
FileInputStream fileInputStream = new FileInputStream(inFile);
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
//建立缓冲输入输出字节流
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//边读边写
int content = 0 ;
while((content = bufferedInputStream.read())!=-1){
bufferedOutputStream.write(content);
// bufferedOutputStream.flush();
}
//关闭资源
bufferedOutputStream.close();
bufferedInputStream.close();
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
}
输入字符流:
———-| Reader 抽象类 所有输入字符流的基类。
—————-| FileReader 读取文件数据的输入字符流。
FileReader的 使用步骤:
1. 找到目标文件。
读文件的两种方式
//方式二:使用缓冲字符数组读取文件的数据 推荐
public static void readTest2() throws IOException{
//找到目标文件
File file = new File("F:\\Demo1.java");
//建立数据的输入通道
FileReader fileReader = new FileReader(file);
//建立缓冲字符数组,读取文件的数据
char[] buf = new char[1024];
int length = 0;
while((length = fileReader.read(buf))!=-1){ // read(char[] buf) 读取到的字符数组存储到了字符数组中,返回了本次读取到的字符个数。
System.out.print(new String(buf,0,length));
}
//关闭资源
fileReader.close();
}
//方式一:每次只会读取一个字符的数据
public static void readTest() throws IOException{
//找到目标对象
File file = new File("f:\\a.txt");
//建立数据的输入通道
FileReader fileReader = new FileReader(file);
//读取文件数据
int content= 0;
while((content=fileReader.read())!=-1){ // FileReader的read()方法每次读取一个字符的数据,如果读到 了文件末尾返回-1表示。
System.out.print((char)content);
}
//关闭资源
fileReader.close();
}
输出字符流 :
——–| Writer 抽象类 输出字符流的基类。
————| FileWriter 向文件写出数据输出字符流.
FileWriter 使用步骤: FileReader
1. 找到目标文件
2. 建立数据的输出通道
3. 写出数据
4. 关闭资源
FileWriter 要注意的事项:
1. new FileWriter(file)的时候 , 如果目标文件不存在,那么会创建目标文件对象, 如果目标文件已经存在了,那么则不再重新创建。
2. 使用new FileWriter(file) 这个构造方法的时候,默认是会先清空文本的数据,然后再写入新的数据。如果需要追加数据则需要使用 new FileWriter(file,true)这个构造方法。
3. 使用FileWriter的write方法的时候,数据是写入了FileWriter内部维护的字符数组中,如果需要把数据真正的写到硬盘上去,需要调用flush方法或者 是close方法或者是内部维护的字符数组已经满了,这时候也会写到硬盘上。
public static void writerTest() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据 的输出通道
FileWriter fileWriter = new FileWriter(file); //第二个参数为true的意义是指追加数据。
//准备数据,把数据写出
String data = "现在雨停了";
fileWriter.write(data);
//刷新输出字符流
fileWriter.flush();
}
总结 :
需求:使用输入输出字符流拷贝java文件.
何时使用字符流:何时使用字节流:
public class CopyJava {
public static void main(String[] args) throws IOException {
//找到目标文件
File inFile = new File("F:\\Demo1.java");
File outFile = new File("E:\\Demo2.java");
//建立数据 的输入输出通道
FileReader fileReader = new FileReader(inFile);
FileWriter fileWriter = new FileWriter(outFile);
//边写边读
char[] buf = new char[1024];
int length = 0 ;
while((length= fileReader.read(buf))!=-1){
fileWriter.write(buf,0,length);
}
//关闭资源
fileWriter.close();
fileReader.close();
}
}