对文件的内容操作主要分为两大类:
分别是:
字符流
字节流
字符流中有两个抽象类:writer reader其对应的子类 FileWriter和FileReader可实现文件的读写操作
BufferedWriter和BufferedReader提供缓冲区功能,用以提高读写效率
字节流有连个抽象类:InputStream和OutStream
其对应的子类有FileInputStream和FileOutStream可实现文件的读写操作
BufferedInputStream和FileOutStream这两个类提供缓冲区功能
为什么要用BufferedWriter和BufferedReader BufferedInputStream和FileOutStream
原理:FileInputStream/FileOutputStream 每次调用系统方法 read()/write() 都会触发一个 IO 操作。BufferedInputStream/BufferedOutputSteam 调用 read()/write() 并不会每次都触发一个 IO 操作,只是写到内部的buffer里面,而只有内部的 buffer 满了或者调用 flush() 才会触发 IO 操作。IO 操作越少,性能越好。
代码转载来自于http://www.cnblogs.com/nerxious/archive/2012/12/15/2818848.html
字符流
实例1:字符流的写入与读取
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class file {
FileWriter w = null;
FileReader r = null;
String path = "D:"+File.separator+"qianming"+File.separator
+"filetest.txt";
public void writer1(){
//第一步创建要操作的文件名称和路径
/*File.separator代表不同系统下面的文件分隔符Linux下为:/ Windows下为:\\*/
/*String path = "D:"+File.separator+"qianming"+File.separator
+"filetest.txt";*/
//由于IO操作会抛出异常,因此在try语句块的外部定义FileWriter的引用
//FileWriter w = null;
//第二步:以file对象加入FileWriter对象
//如果需要追加数据,而不是覆盖,则使用FileWriter(path,true)构造方法
try{
//创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。
w = new FileWriter(path,true);
//将字符串写入到流中,\r\n表示换行想有好的
w.write("cheng is a good boy\r\n");
//如果想马上看到写入效果,则需要调用w.flush()方法
w.flush();
}catch(IOException e){
e.printStackTrace();
}finally{
//如果前面发生异常,那么是无法产生w对象的
//因此要做出判断,以免发生空指针异常
if(w != null) {
try {
//关闭流资源,需要再次捕捉异常
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void reader1()
{
try {
r = new FileReader(path);
//每读取一次,向下移动一个字符单位
try {
int temp1 = r.read();
System.out.println((char)temp1);
int temp2 = r.read();
System.out.println((char)temp2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
//分别判断是否空指针引用,然后关闭流
if(r != null) {
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//方式三:循环读取的简化操作
//单个字符读取,当temp不等于-1的时候打印字符
/*int temp = 0;
while ((temp = r.read()) != -1) {
System.out.print((char)temp);
}
*/
//方式五:读入到字符数组的优化
//由于有时候文件太大,无法确定需要定义的数组大小
//因此一般定义数组长度为1024,采用循环的方式读入
/*
char[] buf = new char[1024];
int temp = 0;
while((temp = r.read(buf)) != -1) {
System.out.print(new String(buf,0,temp));
}
*/
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//利用缓冲区实现复制文件
public class copyFile {
public void copy()
{
String source = "D:"+File.separator+"CloudMusic"+File.separator+"MV"
+File.separator+"Asher Book - Here With You.mp4";
String des = "D:"+File.separator+"CloudMusic"+File.separator+"here with you.mp4";
FileInputStream input = null;
FileOutputStream out = null;
BufferedInputStream bufferedinput = null;
BufferedOutputStream bufferedoutput =null;
try {
input = new FileInputStream(source);
bufferedinput = new BufferedInputStream(input);
out = new FileOutputStream(des);
bufferedoutput = new BufferedOutputStream(out);
byte buf[] = new byte[1024];
int temp=0;
while((temp = bufferedinput.read(buf))!=-1)
{
bufferedoutput.write(buf,0,temp);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if(bufferedinput != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bufferedoutput != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
什么时候该使用字符流,什么时候又该使用字节流呢?
字符流,肯定是用于操作类似文本文件或者带有字符文件的场合比较多
字节流则是操作那些无法直接获取文本信息的二进制文件,比如图片,mp3,视频文件等
在硬盘上都是以字节存储的,只不过字符流在操作文本上面更方便一点而已
为什么要利用缓冲区呢?
像迅雷等下载软件都有个缓存的功能,硬盘本身也有缓冲区
利用缓冲区不必频繁的操作文件,因此,采用缓冲区能够在读写大文件的时候有效提高效率