IO流__【概述】【字符文件的读写和复制】【字符流缓冲区】


IO流概述

IO流(Input  Output)用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流。  
流按流向分为:输入流,输出流。

字节流的抽象基类:
InputStream ,OutputStream。
字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。

字符流的特点:
IO流是用来操作数据的,那么数据的最常见形式是:文件
先以操作文件来演示IO流
需求:在硬盘上创建一个文件并写入一些文字数据
用到Writer的子类:后缀名是父类名,前缀名是功能;在API中找到一个专门用于操作文件的对象:FileWriter
创建FileWriter对象该对象一被初始化就必须要明确要操作的对象;没有空参的构造方法
而且该文件会被创建在指定的目录下,如果该目录已有同名文件则会被覆盖
其实该操作就是在明确数据要存放的目的地

FileWriter示例:

文件写入

import java.io.*;
class IODemo {
	public static void main(String[] args) throws IOException	//抛IO异常
	{
		FileWriter fw = new FileWriter("Demo.txt");//1,创建文本对象
		fw.write("asdff");	//2,调用write方法,将字符串写入到流中
///		fw.flush();			//3,刷新流对象中缓冲区数据;到目的地中
		fw.close();			//4,关闭流资源,并在关闭之前刷新一次缓冲区数据,刷到目的地中
						//flush刷新后流可以继续使用,close刷新后会将流关闭	
	}
}

IO异常的处理:

new 、write、close都会造成IO异常,所以要做处理

import java.io.*;
class FileWriterDemo2 
{
	public static void main(String[] args) 
	{
		FileWriter fw = null;	//将FileWriter外置,以调用finally中的close
		try{
			fw = new FileWriter("Demo.txt");
			fw.write("haha");			
		}
		catch (IOException e){
			System.out.println("catch: "+e.toString());
		}
		finally{	//开启了几个写入流就要关闭几次,切记
			try{
				if(fw!==null)	//一定要判断是否为null,因为close的操作要有对象
				fw.close();		//要对异常进行处理			
			}
			catch (IOException e){
				System.out.println(e.toString());
			}
		}
	}
}

文件的续写

FileWriter(" ",append)方法    append值为true时将数据写入文件末尾处,为false则覆盖原文件

		try
		{		//append值为true时将数据写入文件末尾处,为false则覆盖原文件
			fw = new FileWriter("Demo.txt",true);//传递一个true
			fw.write("换行
文件续写");			
		}

FileRader

文本文件的读取

方法一:read()

该方法一次只读取一个字符,返回值为该字符在码表中对应的int值,到达文件末尾时返回-1

创建一个文件读取流对象,和指定名称的文件相关联
要保证该文件已经存在,否则会发生异常:FileNotFoundException

import java.io.*;
class  FileReaderDemo
{
	public static void main(String[] args)  throws IOException
	{
		FileReader fr = new FileReader("Demo.txt");//创建读取流
//		int ch = fr.read();	//read一次只读取一个字符,多次调用则继续往下读;返回值为该字符在码表中的int值		
		int ch = 0;		//循环获取文本内容
		while ((ch = fr.read())!=-1)//read()到达文件末尾返回-1
		{
			System.out.print((char)ch);
		}
		fr.close();
	}
}

方法二:read(char[] cbuf)

通过字符数组进行获取,该方法一次获取数组个数的字符,返回值为实际获取的元素个数,一般是数组长度,到达文件末尾时返回-1。

read()和 read(char[] cbuf)都有in型的返回值,不同的是前者返回的是该字符在码表中对应的值,后者返回的是该字符数组的元素个数

示例:

import java.io.*;
class FileReader2 
{
	public static void main(String[] args) throws IOException{
		FileReader fr = new FileReader("Demo.txt");
		char[] buf = new char[1024];//定义数组用于存储读取的字数
//		int num = fr.read(buf);	//该read返回数组元素个数
//		sop("num: "+num+" ... "+new String(buf));	
		int num ;//
		while ((num=fr.read(buf)) !=-1){//read(char[] cbuf)到达文件末尾返回-1
			sop(new String(buf,0,num) );
		}
		fr.close();
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}

内存示例:



-------------------------------------------------------------------------------

文件内容的copy

将一个文件内容copy到另一个文件,要做整点掌握
原理:1,创建一个文件,用于接收写入流2,定义读取流和目标文件关联3,通过不断的读写完成数据4,关闭资源
根据文件读取两种方式的不同,有两种copy方式,但原理是一致的
示例:
import java.io.*;
class  CopyTest
{
	public static void main(String[] args) throws IOException
	{
//		copy_1();
		copy_2();
	}
	public static void copy_2()	//方法二:利用数组,每次存取1024个字符,减少循环次数,提高效率
	{
		FileWriter fw = null;
		FileReader fr = null;
		try						//异常要进行处理,不建议throws
		{
			fw = new FileWriter("CopyTest_copy.txt");
			fr = new FileReader("CopyTest.java");
			char[] buf = new char[1024];
			int num;
			while ((num=fr.read(buf)) !=-1){
				fw.write(buf,0,num);//写入字符数组的某一部分,这么定义是因为末尾时num有不满足1024的情况
			}
		}
		catch (IOException e){
			throw new RuntimeException("访问失败");//处理异常,可以定义更加详细的规则
		}
		finally					//关闭流的动作一定要执行,要分开写
		{
			if(fr!=null)//关闭流的动作一定要有对象,所以要做判断
				try{
					fr.close();
				}
				catch (IOException e)
				{}
			if(fw!=null)
				try{
					fw.close();
				}
				catch (IOException e)
				{}
		}
	}
	public static void copy_1() throws IOException//方法一:每次读写一个字符,循环次数多
	{
		FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");//1,写入流 创建目的地
		FileReader fr = new FileReader("CopyTest.java");	//2,读取流 与已有文件关联
		int ch;
		while ((ch=fr.read()) !=-1)//3,读取
		{
			fw.write(ch);		//写入
		}
		fw.close();//4,关闭流
		fr.close();
	}
}

文件的Copy过程简述:
文件读取流对象通过调用系统底层,将硬盘上的文件读取到内存中封装成数组,写入流将数组中的元素写入到硬盘的目的地中,读写完成后关闭两个流资源硬盘中源文件>读取流>内存中数组>写入流>目标文件>关闭流资源


字符流缓冲区

缓冲区的出现是为了提高流的操作效率,在开发中一般都要加缓冲区,提高性能在创建缓冲区之前,必须要现有流对象

写入流缓冲区

BufferedWriter;是Writer的子类
示例:

import java.io.*;
class BufferedWriterDemo 
{
	public static void main(String[] args) throws IOException
	{
		FileWriter fw = new FileWriter("buf.txt");
		BufferedWriter bfw = new BufferedWriter(fw);//将要提高效率的流对象作为参数传递给缓冲区的构造函数
		for (int x= 1; x<5; x++)
		{
			bfw.write("hahahah"+x);	//子类继承自父类的方法
			bfw.newLine();	//换行。缓冲区中跨平台的换行符,		Windows和Linux中换行符是不一样的,为了保证Java的跨平台性
			bfw.flush();	//只要用到了缓冲区,就要记得刷新
		}
		bfw.close();	//关闭缓冲区就是在关闭缓冲区中的流对象,所以不用再进行流对象的关闭动作
	}
}

读取流缓冲区

该方法提供了一个一次读取一行的方法,方便与对文本文件的获取
readLine()方法,该方法返回含有该行内容的字符串,不包含换行符;到达流末尾则返回null

简写示例:

		FileReader fr = new FileReader("buf.txt");//创建读取流 关联文件
		BufferedReader bufr = new BufferedReader(fr);//为了提高效率,将字符读取流对象传递给缓冲区对象的构造函数
		String line = null;
		while ((line = bufr.readLine()) !=null)//readLine到达文件末尾返回null
		{
			System.out.println(line);
		}

通过缓冲区复制文件

import java.io.*;
class CopyTextByBuf 
{
	public static void main(String[] args) 
	{
		BufferedReader bufr = null;
		BufferedWriter bufw = null;
		try
		{
			bufr = new BufferedReader(new FileReader("CopyTextByBuf.java"));//copy当前java文件
			bufw = new BufferedWriter(new FileWriter("BufferedWriter_copy.txt"));
			String line = null;
			while ((line=bufr.readLine()) !=null)//readLine()只返回回车符之前的内容
			{
				bufw.write(line);	//
				bufw.newLine();		//必须要换行
				bufw.flush();
			}
		}
		catch (IOException e){
			throw new RuntimeException("访问失败");
		}
		finally{
			try{
				if(bufr !=null)
					bufr.close();				
			}
			catch (IOException e){
				throw new RuntimeException("读取关闭失败");
			}
			try{
				if(bufw !=null)
					bufw.close();				
			}
			catch (IOException e){
				throw new RuntimeException("写入关闭失败");
			}
		}
	}




原文地址:https://www.cnblogs.com/Joure/p/4337215.html