一、IO体系结构,InputStream /OutputStream 继承树
InputStream /OutputStream 输入/输出流 文件读写 抽象类
![](https://i-blog.csdnimg.cn/blog_migrate/6d43dd77395ea266f071141be982e1ba.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1bc1d11f2a7774ec8937c7cb83b53087.png)
二、主要的几种重要的方法
InputStream 几个重要的方法
int available() 流中的可读取的有效字节长度
void close() 使用流对象后关闭
int read() 这个方法调用会返回流中的下一个字节作为byte值, 文件末尾返回-1
int read(byte[]) 从流中读到的byte
使用FileInputStream 从文件中读取数据
FileInputStream 构造器
FileInputStream (File file) 通过一个文件对象做参数构造输入流对象
FileInputStream (String name) 传入一个字符串(文件路径名)构造连接到指定文件的输入流
OutputStream 几个重要的方法
void close() 使用流对象后关闭
void flush() 将输出流有可还保存在(JVM)内存中的数据强制输出到目标上(文件或者网络上)
void write(int b) 向流中写入一个byte值,此处虽定义为int,但写入的却作为一个byte
void write(byte[]) 将byte数组中的内容输出到流中
void write(byte[] int off, int len) 将byte数组中一部分的内容输出到流中
使用OutputStream 从文件中读取数据
OutputStream 构造器
OutputStream (File file) 构造输出到指定文件file对象的输出流
OutputStream (File file, boolean append)
append 表示输出到文件中的数据是否接在文件中已有数据后面
构造输出到指定文件file对象的输出流
OutputStream (String name) 构造输出到一个字符串(文件路径名)对象的输出流
三、几种不同的文件读写的代码示例
整个字符串的读取和复制
使用FileInputStream/FileOutputStream
package com.yangkang20130719;
import java.io.IOException;
/**
* 输入输出流测试 <方法>文件的读取 , 整个文件的复制
* 使用FileInputStream/FileOutputStream
* @author YangKang 2013.07.19
*
*/
public class BaseIO{
// 定义程序入口主函数
public static void main(String[] args) throws Exception{
BaseIO bio = new BaseIO();
//读取我们当前正在编写的这个java源文件
//String fileName = "E:/HelloJava/GreatJava/src/com/yangkang20130719/BaseIO.java";
String srcFileName = "src/com/yangkang20130719/BaseIO.java";
String srcString = bio.readFile2String(srcFileName);
System.out.println(srcString);
String bakFileName = "src/com/yangkang20130719/BaseIO.txt";
Boolean result = bio.copyFile(srcFileName,bakFileName);
System.out.println("复制结果:"+result);
}
/**
* 读取指定文件名的内容,作为字符串返回
* @param fileName 文件名
* @return 读到的内容作为字符串返回
* @throws IOException 可能会抛出IO异常
*/
private String readFile2String(String fileName) throws IOException {
//构造输入流对象,作为一个InputStream对象使用
//因为创建的对象是InputStream的子类的对象,我们用父类型变量引用,方便统一使用
//创建从文件读取的输入流对象
long startTime = System.currentTimeMillis();
java.io.InputStream ins = new java.io.FileInputStream(fileName);
//根据流中的字节长度,创建一个byte数组,保存读到的数据
byte[] contentByte = new byte[ins.available()];
//将流中的数据读到数组中
ins.read(contentByte);
//将byte数组转换为字符串
String s = new String(contentByte);
long endTime = System.currentTimeMillis();
System.out.println("用字符数组一次性读取整个文件所需时间为:"+(endTime -startTime));
return s;
}
/**
* 简单文件复制方法,使用FileInputStream/FileOutputStream
* @param srcFile 源文件名
* @param destFile 目标文件名
* @return 可能抛出IO异常
* @throws IOException 是否COPY成功
*/
private Boolean copyFile(String srcFile, String destFile) throws IOException {
//创建从源文件来的输入流对象
java.io.InputStream ins = new java.io.FileInputStream(srcFile);
//创建输出流对象:默认写入方式(如果文件中已有内容则覆盖原来内容)
java.io.OutputStream ous = new java.io.FileOutputStream(destFile);
//获取复制前的时刻
long startTime = System.currentTimeMillis();
int i = 0;
//每次从输入流中读取一个字节,直到读取到文件末尾
while((i=ins.read()) != -1){
//将该字节写入到输出流中
ous.write(i);
}
ins.close();
//清空输出流的缓存并关闭
ous.flush();
ous.close();
//获取复制后的时刻
long endTime = System.currentTimeMillis();
//输出整个复制过程所用的时间
System.out.println("复制文件所用时间为:"+(endTime - startTime));
return true;
}
}
依次按顺序每个字符的读取和文件复制
使用FileInputStream/FileOutputStream
package com.yangkang20130719;
import java.io.File;
import java.io.IOException;
/**
* 输入输出流测试 <方法>文件的读取 , 整个文件OneByOne的复制
* @author YangKang 2013.07.19
*
*/
public class FileIO {
public static void main(String[] args) throws IOException {
FileIO fio = new FileIO();
String srcFileName = "src/com/yangkang20130719/FileIO.java";
String srcString = fio.readFileOneByOne(srcFileName);
System.out.println(srcString);
//在给定路径下新建一个文件
File file = new File("src/com/yangkang20130719/text.bak");
String bakFileName = ("src/com/yangkang20130719/text.bak");
fio.copyFile(srcFileName,bakFileName);
System.out.println(bakFileName+" 复制成功");
}
/**
* 读取指定文件名的内容,作为字符串返回
* @param fileName 文件名
* @return 读到的内容作为字符串返回
* @throws IOException 可能会抛出IO异常
*/
private String readFileOneByOne(String fileName) throws IOException {
//创建从已有文件来的输入流对象
java.io.InputStream ins = new java.io.FileInputStream(fileName);
long startTime = System.currentTimeMillis();
int i = -1;
//根据流中的字节长度,创建一个byte型数组,保存读取到的数据
int size = ins.available();
byte[] contentByte = new byte[size];
int count = 0;
//从输入流中读取一个字节,直到文件末尾
while((i=ins.read()) != -1){
contentByte[count++] = (byte) i;
}
//System.out.println(size);
//System.out.println(count);
//将byte数组转换为字符串
String s = new String(contentByte);
long endTime = System.currentTimeMillis();
//输出整个读取过程所用的时间
System.out.println("用字节数组一个一个读取文件的没一个字节所用时间为:"+(endTime - startTime));
return s;
}
/**
* 简单文件复制方法
* @param srcFile 源文件名
* @param destFile 目标文件名
* @throws IOException 可能抛出IO异常
*/
public void copyFile(String srcFile,String destFile) throws IOException{
//创建从源文件来的输入流对象
java.io.InputStream ins = new java.io.FileInputStream(srcFile);
//获取复制前的时刻
long startTime = System.currentTimeMillis();
//创建输出流对象:默认写入方式(如果文件中已有内容则覆盖原来内容)
java.io.OutputStream ous = new java.io.FileOutputStream(destFile);
int i = 0;
//每次从输入流中读取一个字节,直到读取到文件末尾
while((i=ins.read()) != -1){
//将该字节写入到输出流中
ous.write(i);
}
ins.close();
//清空输出流的缓存并关闭
ous.flush();
ous.close();
//获取复制后的时刻
long endTime = System.currentTimeMillis();
//输出整个复制过程所用的时间
System.out.println("复制文件所用时间为:"+(endTime - startTime));
}
}
使用 BufferedOutputStream/BufferedOutputStream类 对文件的读取和文件的复制
package com.yangkang20130719;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 输入输出流测试 ,使用 BufferedOutputStream/BufferedOutputStream类 对文件的读取和文件的复制
* BufferedStream特点:读取写入速度比FileStream要快,默认缓冲区大小8192K
* @author YangKang 2013.07.19
*
*/
public class BufferedIO{
// 定义程序入口主函数
public static void main(String[] args) throws Exception{
BufferedIO bio = new BufferedIO();
//读取我们当前正在编写的这个java源文件
String srcFileName = "src/com/yangkang20130719/BufferedIO.java";
String srcString = bio.readFile2String(srcFileName);
System.out.println(srcString);
String bakFileName = "src/com/yangkang20130719/BufferedIO.txt";
Boolean result = bio.copyFile(srcFileName,bakFileName);
System.out.println("复制结果:"+result);
}
/**
* 读取指定文件名的内容,作为字符串返回
* 使用BufferedStream类读写文件
* @param fileName 文件名
* @return 读到的内容作为字符串返回
* @throws IOException 可能会抛出IO异常
*/
private String readFile2String(String fileName) throws IOException {
//构造输入流对象,作为一个InputStream对象使用
//因为创建的对象是InputStream的子类的对象,我们用父类型变量引用,方便统一使用
//创建从文件读取的输入流对象
long startTime = System.currentTimeMillis();
FileInputStream ins = new FileInputStream(fileName);
//创建一个缓冲输入流对象,将字节输入流对象转换为缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(ins);
//根据流中的字节长度,创建一个byte数组,保存读到的数据
byte[] contentByte = new byte[ins.available()];
//将流中的数据读到数组中
bis.read(contentByte);
ins.close();
//将byte数组转换为字符串
String s = new String(contentByte);
long endTime = System.currentTimeMillis();
System.out.println("用字符数组一次性读取整个文件所需时间为:"+(endTime -startTime));
return s;
}
/**
* 使用BufferedStream类复制文件
* @param srcFile 源文件名
* @param destFile 目标文件名
* @return 可能抛出IO异常
* @throws IOException 是否COPY成功
*/
private Boolean copyFile(String srcFile, String destFile) throws IOException {
//创建从源文件来的输入流对象
java.io.InputStream ins = new java.io.FileInputStream(srcFile);
//创建一个缓冲输入流对象,将字节输入流对象转换为缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(ins);
//创建输出流对象:默认写入方式(如果文件中已有内容则覆盖原来内容)
FileOutputStream ous = new FileOutputStream(destFile);
//创建一个缓冲输出流对象,将字节输出流对象转换为缓冲输出流对象
BufferedOutputStream bos = new BufferedOutputStream(ous);
//获取复制前的时刻
long startTime = System.currentTimeMillis();
int i = 0;
//每次从输入流中读取一个字节,直到读取到文件末尾
while((i=bis.read()) != -1){
//将该字节写入到输出流中
bos.write(i);
}
ins.close();
//清空输出流的缓存并关闭
ous.flush();
ous.close();
//获取复制后的时刻
long endTime = System.currentTimeMillis();
//输出整个复制过程所用的时间
System.out.println("复制文件所用时间为:"+(endTime - startTime));
return true;
}
}
使用InputStreamReader读取文件
package com.yangkang20130719;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* IO_Example3 文件读取
* 使用InputStreamReader读取文件
* @author YangKang 2013.07.19
*
*/
public class IO_Example3 {
public static void main(String[] args) {
try {
//获取读取文件前的时间
long startTime = System.currentTimeMillis();
//创建一个文件对象
File file = new File("src/com/yangkang20130719/","IO_Example3.txt");
//创建文件字节输入流
FileInputStream fis = new FileInputStream(file);
//创建一个字符流对象,使字节流对象转换为字符流对象
InputStreamReader isr = new InputStreamReader(fis);
int rs;
System.out.println("The effective size of IO_Example1 is:"+fis.available());
System.out.println("The content of IO_Example3 is:");
while((rs =isr.read()) != -1){
//在循环中读取输入流的数据
System.out.print((char)rs);
}
fis.close();
//获取读取文件后的时间
long endTime = System.currentTimeMillis();
System.out.println("读取整个文件用时:"+(endTime-startTime));
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用OutputStreamWriter复制文件
package com.yangkang20130719;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* IO_Example4 文件拷贝
* 使用OutputStreamWriter复制文件
* @author YangKang 2013.07.19
*
*/
public class IO_Example4 {
public static void main(String[] args) {
//创建一个文件对象
File filein = new File("src/com/yangkang20130719/","IO_Example4.txt");
//创建一个文件对象
File fileout = new File("src/com/yangkang20130719/","IO_Example4.txt.bak");
//创建文件字节输入流对象
FileInputStream fis;
try {
//如果文件不存在,就创建新文件
if(!filein.exists()){
filein.createNewFile();
}
if(!fileout.exists()){
fileout.exists();
}
//实例化字节输入流对象
fis = new FileInputStream(filein);
//实例化一个字节输出流对象
FileOutputStream fos = new FileOutputStream(fileout,true);
//创建一个字符输入流对象,将字节输入流对象转换为字符输出流对象
InputStreamReader isr = new InputStreamReader(fis);
//创建一个字符输出流对象,将字节输出流对象转换为字符输出流对象
OutputStreamWriter osr = new OutputStreamWriter(fos);
int is;
while((is =isr.read()) != -1){
//在循环中读取输入流的数据
osr.write(is);
}
isr.close();
osr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用FileReader读取文件
package com.yangkang20130719;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
/**
* IO_Example5 文件读取
* 使用FileReader读取文件
* @author YangKang 2013.07.19
*
*/
public class IO_Example5 {
public static void main(String[] args) {
try {
//创建一个文件对象
File file = new File("src/com/yangkang20130719/","IO_Example5.java");
//创建文件字符输入流对象
FileReader fr = new FileReader(file);
char[] data = new char[512];
int rs = 0;
while((rs =fr.read(data)) != -1){
//在循环中读取输入流的数据
String str = new String(data,0,rs);
System.out.println(str);
}
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用FileWriter写入文件
package com.yangkang20130719;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* IO_Example6 文件复制
* 使用FileWriter写入文件
* @author YangKang 2013.07.19
*
*/
public class IO_Example6 {
public static void main(String[] args) {
try {
//创建一个文件对象
File file = new File("src/com/yangkang20130719/","IO_Example6.txt");
//如果文件不存在,创建新文件
if(!file.exists()){
file.createNewFile();
}
//创建文件字符输入流对象
FileReader fr = new FileReader("src/com/yangkang20130719/IO_Example6.java");
//创建文件字符输出流对象
FileWriter fw = new FileWriter(file);
char[] data = new char[512];
int rs = 0;
while((rs =fr.read()) != -1){
//在循环中将数据写入字符输出流
fw.write(rs);
}
fr.close();
//fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用BufferedReader读取文件
package com.yangkang20130719;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
/**
* IO_Example7 文件读取
* 使用BufferedReader读取文件
* @author YangKang 2013.07.19
*
*/
public class IO_Example7 {
public static void main(String[] args) {
try {
//创建一个文件对象
File file = new File("src/com/yangkang20130719/","IO_Example7.java");
//创建文件字符输入流对象
FileReader fr = new FileReader(file);
//创建文件缓冲字符输入流
BufferedReader br = new BufferedReader(fr);
String aline;
while ((aline = br.readLine()) != null) {
String str = new String(aline);//按行读取文本
System.out.println(str);
}
fr.close();
br.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
使用BufferedWriter复制文件
package com.yangkang20130719;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* IO_Example8 文件复制
* 使用BufferedWriter写入文件
* BufferedWriter类 中提供了newLine()方法,
* 而Writer类中无此方法,该方法是换行标记
* @author YangKang 2013.07.19
*
*/
public class IO_Example8 {
public static void main(String[] args) {
try {
//创建一个文件对象
File file = new File("src/com/yangkang20130719/","IO_Example8.txt");
//如果文件不存在,创建新文件
if(!file.exists()){
file.createNewFile();
}
//创建文件字符输入流对象
FileReader fr = new FileReader("src/com/yangkang20130719/IO_Example8.java");
//创建文件缓冲字符输入流对象
BufferedReader br = new BufferedReader(fr);
//创建文件字符输出流对象
FileWriter fw = new FileWriter(file);
//创建文件缓冲字符输入流
BufferedWriter bw = new BufferedWriter(fw);
String str = null;
while((str = br.readLine()) !=null){
//为读取的文本添加回车
bw.write(str + "\n");
}
//关闭输入输出流
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结:Java中的IO的类库非常的庞大,选择性非常的多,当面临一个问题时,往往不知道如何下手!
在编写各种IO结构和测试的时候,发现的一些一般的结论:相同的条件下,使用整个文件的读取和写入比一
个字节一个字节的方式对文件的读取和写入速度要快;使用 BufferedOutputStream/BufferedOutputStream
类 对文件的读取和写入比使用FileInputStream/FileOutputStream类 对文件的读取和写入速度要快的多;
而BufferedReader/BufferedWriter类(用于逐行读取) 对文件的读取和写入比FileReader/ FileWriter类
对文件的读取和写入速度要快的多;
他们之间的继承关系看下面几条语句就知道了、、、
InputStream is = new BufferedInputStream(new FileInputStream(new File(file)));
OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(file)));
BufferedReader br = new BufferedReader(new FileReader(new File(file)));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(file)));
根据我的理解,在效率不是非常重要的情况下,一般情况下可能只需要考虑两种情况,即想按照字节去读取,
还是想按照行去读取,而一般情况无论采取什么方式去读取,最佳的方式都莫过于用Buffered..但是又要考虑
到Buffered..默认的缓冲区大小是8192K,所以具体情况具体分析,按文件读写的需要来选择读写方式无疑是
非常明智的。