IO体系结构,文件流式输入输出

 

一、IO体系结构,InputStream /OutputStream  继承树

 

InputStream /OutputStream  输入/输出流   文件读写  抽象类
 

 

 
 
二、主要的几种重要的方法
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,所以具体情况具体分析,按文件读写的需要来选择读写方式无疑是

 

非常明智的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值