1)从指定的文件中读取数据,向指定的文件中写入数据;
2)核心类:
InputStream----->FileInputStream----->BufferedInputStream 把文件读取到内存中
OutputStream--->FileOutputStream--->BufferedInputStream 从内存中写出文件到本地
3)文件读写的步骤: 其实编程也很简单,要知道实现某个功能的步骤是什么,每一步要做什么事情?
一、封装数据源(要读取哪个文件到内存)
二、封装目的地(把内存中的文件写出到哪)
三、读取数据
四、写入数据
五、关闭流(释放与文件读写相关的系统资源,其实是硬件资源)
4)文件读写特别耗设备性能,引起发热。
5)文件读写一般会抛出异常;
6)一次读取一个字节数组,减少了读取次数,提高了文件读写效率。
package com.crs.demo.ui.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* Created on 2016/8/25.
* Author:crs
* Description:测试文件流
*/
public class DemoEnd6 {
//需求:使用字节流四种方式复制mp3文件,并计算复制所需的时间。
//基本的流: 一次一个字节,一次一个字节数组
//高效的流: 一次一个字节,一次一个字节数组
//步骤:1)封装数据源、2)封装目的地、3)读取数据、4)写入数据、5)关闭流、
public static void main(String[] args) {
long start = System.currentTimeMillis();
//method1();
//method2();
//method3();
method4();
long end = System.currentTimeMillis();
System.out.print("共耗时" + (end - start) + "毫秒");
}
private static void method4() {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\1.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("4.avi"));
//每次读取和写入一个字节数组
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
//其实是释放与文件读写相关的硬件资源。
bis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void method3() {
try {
//使用高效的流进行文件读写
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\1.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("3.avi"));
int by = bis.read();
while (by != -1) {
bos.write(by);
}
bis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void method2() {
//每次一个字节数组
try {
FileInputStream fis = new FileInputStream("D:\\1.avi");
FileOutputStream fos = new FileOutputStream("2.avi");
//创建字节数组,每次读取和写入一千字节
byte[] bytes = new byte[1024];
int len;
//每次读取一个字节数组
while ((len = fis.read(bytes)) != -1) {
//最后一次可能不是一个字节数组
fos.write(bytes, 0, len);
}
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void method1() {
try {
FileInputStream fis = new FileInputStream("D:\\1.avi");
FileOutputStream fos = new FileOutputStream("1.avi");
//读取数据,每次一个字节
int by = fis.read();
while (by != -1) {
//写入数据,每次一个字节
fos.write(by);
}
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件流是用来处理设备之间数据传输的。
java对文件的操作是以文件流的方式;java用于操作文件流的类都在IO包中;
把文件流理解为通道就好了。
转换流和高效流都是对基本流的封装!
转换流操作文件和高效流的步骤一样
InputStream---->FileInputStream---->BufferedInputStream
OutputStream--->FileOutputStream--->BufferedOutputStream
最好把文件的读写操作,写到一个单独的方法里面,这样好处理异常。
使用高效的流进行文件读写。
转换流:
InputStreamReader: 字符输出流
OutputStreamWriter: 字符输入流
——————————————————————————————————
流的分类:
1)根据内存流向:
输入流:从流中读取数据;read 把数据读取到内存中
输出流:向流中写入数据;write 把数据从内存中写出
2)根据文件类型
字节流:可以操作任何文件.主要用于传输二进制文件,比如图片、视频、音频资源。
字节输入流:读取数据 InputStream--->FileInputStream
字节输出流:写入数据 OutputStream--->FileOutputStream
字符流:只能操作文本文件;专门用于处理汉字的;
字符输入流:读取数据 Reader
字符输出流:写入数据 Writer 重点记忆这四个类(这是文件读写的核心类)
——————————————————————————————————
FileOutputStream
构造方法
FileOutputStream(File file) 传递进去一个文件对象
FileOutputStream(String name) 传递一个文件的绝对路径也是可以的
FileOutputStream(File file,boolean append)
FileOutputStream(String name,boolean append)
字节流写数据的方式: 注意参数为字节数组,犯过错的
write(int a)方法; 写入一个字节 相当于一个英文字母
write(byte[] b)方法; 写入一个字节数组
write(byte[] b,int off,int len)方法; 写入一个字节数组一部分的方法 参数:off 获取元素的起始角标位置 len表示获取获取几个元素
——————————————————————————————————
字节输出流 写数据常见的问题:
1)创建字节输出流到底做了哪些事情? 做了三件事情
2)写入成功后为何要close流呢?关闭此文件输出流,并释放与此流相关的所有系统资源;流关闭后close(),不能再用于写入字节。
3)如何实现数据的换行写入? 每个操作系统的换行是不一样的 windows操作系统中的换行是"\r\n" liunx操作系统中的换行是“\n”
4)如何实现数据的追加写入? 在原有的数据的基础上,再增加数据。
5)FileOutputStream写出数据加入异常处理. 对文件的读写操作一定要进行try...catch...或者throws IOException{}
——————————————————————————————————
文件输入流:
FileInputStream 读取数据,父类是抽象类.
从文件系统中的某个文件获的输入的字节
FileInputStream(File file) 传递进去一个文件
FileInputStream(String name) 传递一个文件的绝对路径也是可以的
read(); //读取一个字节 在读取的时候,如果已经达到文件的末尾,就返回-1;
read(byte[] b);//读取一个字节数组
循环读取字节数据
A:一次读取一个字节
B:一次读取一个字节数组;减少了读取次数,提高了效率;
读取数据两种方式的比较:每次读取一个字节,写入的时候也每次写入一个字节。读取一个自己数组,写入的时候,写入真正读取到的字节数。
——————————————————————————————————
使用高效的流进行处理数据的读写操作
高效的流对象,里面传入的是基本流。
1)BufferedOutputStream 字节缓冲输出流 继承自FileOutputStream对这些基本的流进行了封装
2)BufferedInputStream 字节缓存输入流 继承自FileInputStream会在内部创建一个缓冲区数组
BufferedInputStream(InputStream in) 构造函数 需要一个基本的流
四种方式实现文件读写:
基本的流: 一次一个字节
高效的流: 一次一个字节
比较四种流的性能:
四个类、其中的读写方法、字节流
7)由于字节流操作中文不方便,就出现了转换流. 使用字符流操作中文.
字符流=字节流+编码表;
编码表:由字符以及对应的数字组成的一张表。编码表可以理解为字典。
常见的编码表
字符串中的编码问题:
编码:把看懂的转化成看不懂的;解码:把看不懂的转化成看懂的。
UnsupportedEncodingException:不支持的编码异常
FileNotFoundException:文件找不到的异常
平台默认的编码字符集;自己指定编码字符集;
其实编码问题很简单:只需要编码和解码使用同一个编码表即可。
8)转换流 可以指定编码表
InputStreamReader(InputStreamReader inputStream)
InputStreamReader(InputStreamReader inputStream,String 编码集)