IO字符流阶段总结

IO:
用于设备上的数据处理。

IO的分类:
	字符流,字节流。
	在早期时,只有字节流,后期为了方便处理不同的文字出现了字符流。
	因为编码的原因,而出现字符流。

	所有IO体系中的对象通常都以自己所属的父类名作为子类名的后缀名。

	IO体系顶层类:
	四个抽象基类:
	字节流:
	InputStream OutputStream。
	字符流:
	Reader Writer。

	使用了字符流中的子类对象。因为要操作的是硬盘的文件。
	所以使用了FileReader,FileWriter.

	需求:
	在硬盘上建立一个文件,并往文件中写入内容。
	1,建立字符写入流对象。
		建立了流对象,调用了window资源,在指定位置创建了demo.txt文件。先建立了数据存储的目的。
		但是因为传递参数的原因,有可能出现IO异常。

		如果指定目录下已有该文件会出现覆盖操作。
		如果需求是在原有文件中进行数据的续写。要在构造时,传入另一个参数true。new FileWriter("demo.txt",true);
	FileWriter fw = new FileWriter("demo.txt");

	2,调用流对象写入方法,将数据写入到流中。
	fw.write("abcdec");//fw.write("abcd".toCharArray());

	3,对流中的数据进行刷新,将数据刷到目的当中。
	fw.flush();
	可以进行频繁写入,并刷新。。。。
	4,关闭资源,会刷新它先。
	fw.close();
	

	public void show()
	{
		FileWriter  fw = null;
		try
		{
			fw = new FileWriter("c:/demo.txt");
			fw.write("abced");
		}
		catch(IOException e)
		{
			System.out.println(e.toString());
		}
		finally
		{
			/*
			if(fw!=null)
				try 
				{
					fw.close();
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			*/
			closeAll(fw,null);
		}
	}
	

	需求:
	读取硬盘上的数据,并将其打印在控制台上。
	//1,建立字符读取流对象。先用流对象与要读取的文件相关联。必须要保证该是存在的,否则会发生FileNotFoundException。
	FileReader fr = new FileReader("demo.txt");

	//2,定于一个临时容器,因为读到的都是字符数据,所以建立一个字符数组。
	该数组的长度如何定义呢?以计算机的基本单位或者其整数倍作为长度
	char[] arr = new char[1024];

	//3,使用读取流对象的read(arr)方法,将读取到每一个字符数据存入到数组中。
	该方法会读到的字符个数。其实就是往数组里面装的元素的个数。
		int num = 0;

		while((num=fr.read(arr))!=-1)
		{
			System.out.println(new String(arr,0,num));
		}

	//4,关闭资源。
	fr.close();

	注意:读取流还有一个read()方法,该方法是没有参数的,一次读一个字符,并将读到的字符返回。
	int ch = 0;
	while((ch=fr.read())!=-1)
	{
		System.out.println((char)ch);
	}



	需求:
	copy文本文件

	public void show()
	{
		FileReader fr = null;
		FileWriter fw = null;

		try
		{
			fr = new FileReader("demo.txt");
			fw = new FileWriter("copydemo.txt");

			char[] arr = new char[1024];
			int num = 0;

			while((num=fr.read(arr))!=-1)
			{
				fw.write(arr,0,num);
			}
		}
		catch(Exception e)
		{
			ystem.out.println(e.toString());
		}
		finally
		{
			closeAll(fw,fr);
		}

	}
	public void closeAll(Writer w,Reader r)
	{
		if(w!=null)
			try 
			{
				w.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		if(r!=null)
			try 
			{
				r.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
	}


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

为了提高了对流的操作效率,出现了缓冲技术,提高了流的操作效率。
该缓冲技术也被封装成了对象。
对于字符流:
BufferedWriter:
	newLine();跨平台的换行符。
BufferedReader
	readLine():一次获取一行数据。不包括回车符。

缓冲技术,是为了提高流的效率,所以缓冲对象在初始化的时必须要有流。
使用缓冲技术一定要使用flush();

	需求:通过缓冲技术对文本数据进行copy.
	public void show()
	{
		FileReader fr = new FileReader("demo.txt");
		BufferedReader bufr = new BufferedReader(fr);

		FileWriter fw = new FileWriter("bufdemo.txt");
		BufferedWriter bufw = new BufferedWriter(fw);

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			bufw.write(line);
			bufw.newLine();
			bufw.flush();
		}

		bufw.close();
		bufr.close();

		//closeAll(bufw,bufr);
	}


缓冲技术的出现对流的读取和写入都进行了增强。
其实就是将一个数组封装在缓冲对象中。

这里就用到了一种设计模式:装饰设计模式。
该模式可以对类中的功能进行增强,优化了继承。

通过继承一样可以完成对类功能的增强,为了还要装饰呢?

Writer
	|--FileWriter
		|--BufferFileWriter
	|--MediaWriter
		|--BufferMediaWriter
	|--DateWriter
		|--BufferDateWriter

为了增强子类的操作效率。想到了缓冲技术。通过继承的方法,在子类中建立带缓冲技术的功能。

但是在设计方式中,发现该体系变的比较臃肿,而且功能都在重复。
那么,进一步优化该设计。
可不可以将缓冲技术进行抽取,单独进行描述。
想要对这些子类进行增强时,只要将每一个子类作为参数传递给缓冲类的构造函数即可。

Writer
	|--FileWriter
	|--MediaWriter
	|--DateWriter
	|--Buffer

class Buffer
{
	Buffer(FileWriter w)
	{}
	Buffer(MediaWriter w)
	{}
	Buffer(DateWriter w)
	{}	
}
发现这样设计不具备扩展性。
因为传递的都是Writer的子类,只要建立父类引用即可,多态。

class  Buffer extends Writer
{
	Buffer(Writer w)
	{}
}


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

readLine():原理:其实还是用底层read方法,只不过将每一次读到的字符进行临时存储,	
	  当读到回车符,将临时存储的数据一次性返回。

class MyBufferedReader 
{
	private Reader  r;
	MyBufferedReader(Reader r)
	{
		this.r = r;
	}
	public String myReadLine()throws IOException
	{
		StringBuilder sb = new StringBuilder();

		int ch = 0;
		while((ch=r.read())!=-1)
		{
			if(ch=='\r')
				continue;
			if(ch=='\n')
				return sb.toString();
			else
				sb.append((char)ch);
		}
		if(sb.length()!=0)
			return sb.toString();
		return null;
	}
	public void myClose()throws IOException
	{
		r.close();
	}
}


-----
带行号
class MyLineNumberReader extends MyBufferedReader
{	
	private int myNumber;
	MyLineNumberReader(Reader r)
	{
		super(r);
	}
	public void setMyNumber(int myNumber)
	{
		this.myNumber = myNumber;
	}
	public int getMyNumber()
	{
		return myNumber;
	}

	public String myReadLine()throws IOException 
	{
		myNumber++;
		return super.myReadLine();
	}
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值