您的位置:首页 > 职场人生

黑马程序员java 基础之io流中的字符流

2015-01-07 23:16 603 查看
------- android培训java培训、期待与您交流! ----------
IO流是用于操作数据的,有四个基类:字节流InputStream,OutputStream; 字符流:Reader,Writer

1.字符流:Writer 写入

练习:在硬盘上创建一个文件,并写入一些数据

import java.io.*;
class FileWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个FileWriter对象,该对象一旦被初始化,就要明确被操作的文件;
		//而且该文件会被创建到指定目录下,如果该目录下已有同名文件,将被覆盖
		//其实该步骤就是在明确数据要存放的目的地
		FileWriter fw=new FileWriter("demo.txt");

		//调用write方法,将字符串写入到流中
		fw.write("abcde");

		//刷新流对象中的缓冲中的数据
		//将数据刷到目的地中;
		fw.flush();

		//刷新流中的缓冲数据,然后关闭该流
		fw.close();
	}
}
对该IO异常的专业处理

import java.io.*;
class FileWriterDemo2
{
	public static void main(String[] args)
	{
		FileWriter fw=null;//建立引用,作用于整个函数
		try
		{
		 fw= new FileWriter("k:\\demo.txt");//初始化
		 fw.write("abdcdedf");
		}
		catch(IOException e)
		{
			System.out.println(e.toString());
		}
		finally
		{
			try
			{
				if(fw!=null)
					fw.close();
			}
			catch(IOException e)
			{
				System.out.println(e.toString());	
			}
		}		
	}
}


2.字符流 :Reader 读取
读取方式1:读一个字符

import java.io.*;
class FileReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个文件读取对象,和指定名称的文件相关联
		FileReader fr= new FileReader("demo.txt");
		
		//调用读取流对象的read方法
		//一次读取一个字符,并自动往下读
		/*
		while(true)
		{
			int ch=fr.read();
			if(ch==-1)
			break;
			System.out.println("ch="+(char)ch);
		}
		*/
		int ch=0;
		while((ch=fr.read())!=-1)
		{
			System.out.println("ch="+(char)ch);
		}
		fr.close();
	}
}


读取方式2:读取字符串

import java.io.*;
class FileReaderDemo2
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr=new FileReader("demo.txt");

		//read(char[])返回的是读到字符的个数
		char[] buf=new char[1024];
		int num=0;
		
		while((num=fr.read(buf))!=-1)
		{
			System.out.println(new String(buf,0,num));
		}
		fr.close();
		
	}
}


练习:读取一个.java文件,并打印在控制台

import java.io.*;
class FileReaderTest
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr=new FileReader("CalendarDemo.java");
		char[] buf =new char[1024];
		int len=0;
		while((len=fr.read(buf))!=-1)
		{
			System.out.println(new String(buf,0,len));
		}

		fr.close();
	}
}


练习2:将d盘一个文本文件复制到e盘

import java.io.*;
class ReadWriteTest
{
	public static void main(String[] args) throws IOException
	{
			FileWriter fw=null;
			FileReader fr=null;
		try
		{
		 fw=new FileWriter("e:\\demo.txt");//创建一个文件,等待数据写进来
		 fr=new FileReader("d:\\java0217\\day18\\SystemDemo.java");//读取要复制的文件

		char[] buf= new char[1024];//创建一个数组存放读取的文件数据
		int len=0;
		while((len=fr.read(buf))!=-1)
		{
			fw.write(buf,0,len);
		}
		}
		catch(IOException e)
		{
			throw new RuntimeException("读写失败");
		}
		
		finally
		{
			try
			{
				if(fr!=null)
					fr.close();
			}
			catch(IOException e)
			{
				System.out.println(e.toString());
			}

			try
			{
				if(fw!=null)
					fw.close();
			}
			catch(IOException e)
			{
				System.out.println(e.toString());
			}
		}
	}
}


3.字符流中的缓冲区: 缓冲区是为了提高流的操作速率出现,创建缓冲区之前必须要有流对象

BufferedReader 字符读取流缓冲区:

import java.io.*;
class BufferedReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个文件读取对象,和指定名称的文件相关联
		FileReader fr=new FileReader("buf.txt");
		//将字符读取流对象作为参数传递给缓冲对象的构造函数
		BufferedReader bufr= new BufferedReader(fr);

		String s=null;
		while((s=bufr.readLine())!=null)
		// readLine()方法是整行整行的读取
		{
		   System.out.println(s);
		}
		bufr.close();
	}
}


BufferedWriter 写入流缓冲区

import java.io.*;
class BufferedWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建字符写入流对象
		FileWriter fw=new FileWriter("buf.txt");
		
		//加入缓冲技术,将需要提高效率的流对象作为参数传递给缓冲区的构造函数
		BufferedWriter bufw= new BufferedWriter(fw);
		
		for(int x=0;x<5;x++)
		{
		bufw.write("abcde"+x);//仅此一步,发现文件中还是没有数据
				//所以用到缓冲区,必须要刷新流中的数据

		bufw.newLine();//换行,此换行符具有跨平台性

		bufw.flush();
		}

		bufw.close();//关闭缓冲区就是关闭了缓冲区中的流对象,所以不用再关闭流对象
	}		
}


练习:通过字符流缓冲区复制一个.java文件

import java.io.*;
class BufferedCopy
{
	public static void main(String[] args)
	{
		BufferedReader bufr=null;//建立引用
		BufferedWriter bufw=null;//<span style="font-family:Arial, Helvetica, sans-serif;">建立引用</span>

		try
		{
		bufr=new BufferedReader(new FileReader("BufferedWriterDemo.java"));//将读取的数据流存入到读取缓冲对象中
		bufw=new BufferedWriter(new FileWriter("CopyDemo.txt"));//将要写入的数据流存入到缓冲对象中
		
		String line=null;
		while((line=bufr.readLine())!=null)
		   {
			bufw.write(line);//将整行读取的数据写入目的地
			bufw.newLine();//转行
			bufw.flush();//刷新数据
		    }

		}
		catch(IOException e)
		{
			throw new RuntimeException("读写失败");
		}

		finally
		{
			try
			{
				if(bufr!=null)
					bufr.close();
			}
			catch(IOException e)
			{
				System.out.println(e.toString());
			}

			try
			{
				if(bufw!=null)
					bufw.close();
			}
			catch(IOException e)
			{
				System.out.println(e.toString());
			}
		}
	}
}

4.装饰设计模式:将已有对象传入,并基于已有功能,提供加强功能

装饰类通常会通过构造方法接收被装饰的对象。

创建一个和BufferedReader类似的字符缓冲区,缓冲区读取数据速率更高,但是也是基于FileReader中的read方法,所以缓冲区就是一个装饰类

import java.io.*;
class MyBufferedReader
{
	private FileReader r;
	MyBufferedReader(FileReader r)
	{
		this.r=r;
	}
	//可以一次读一行数据的方法

	public String myReaderLine()throws IOException
	{
	//定义一个临时容器:StringBuilder
	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 MyBufferedReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr=new FileReader("buf.txt");

		MyBufferedReader mbf=new MyBufferedReader(fr);
		
		String line=null;
		while((line=mbf.myReaderLine())!=null)
		{
			System.out.println(line);
		}
		mbf.myclose();
	}
}
继承和装饰的区别:继承体系会过于臃肿,类与类之间联系过密;而装饰类会更加灵活,降低类与类之间的关系,装饰类和被装饰类都属于一个体系

LineNumberReader:跟踪行号的缓冲字符输入流,可以获取行号

import java.io.*;
class LineNumberReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建文件读取流对象,并将读取的文件与流对象相关联
		FileReader fr=new FileReader("MyBufferedReader.java");
		//创建行号缓冲字符流,并将流对象传入
		LineNumberReader ln=new LineNumberReader(fr);

		String line=null;
		ln.setLineNumber(100);//设置读取的起始行号
		while((line=ln.readLine())!=null)//当读取的行的内容不为空时打印行内容
		{
			System.out.println(ln.getLineNumber()+"--"+line);
		}
		ln.close();
	}
}
下面自己模拟一个LineNumberReader

import java.io.*;
class MyLineNumberReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr=new FileReader("BufferedCopy.java");//创建字符流对象,并与文件相关联

		MyLineNumberReader mnr=new MyLineNumberReader(fr);//创建跟踪行号的字符缓冲区,并将fr存入
		
		String line=null;
		mnr.setLineNumber(100);
		while((line=mnr.myReaderLine())!=null)
		{
			
			System.out.println(mnr.getLineNumber()+"::"+line);
		}
		mnr.myclose();
	}
}

/*

class MuLineNumberReader extends MyBufferedReader  //继承MyBufferedReader类,可以优化代码
{
	
	private int LineNumber;
	MyLineNumberReader(Reader r)
	{
		super(r); //继承父类方法
	}
	public String myReaderLine()throws IOException    //创建读行方法
	{
		LineNumber++;
		return super.myReadLine();
	}
	public void setLineNumber(int LineNumber)  //设置行方法
	{
		this.LineNumber=LineNumber;
	}
	public int getLineNumber()  //获取行方法
	{
		return LineNumber;
	}
	
}

*/

class MyLineNumberReader
{
	private Reader r;
	private int LineNumber;
	MyLineNumberReader(Reader r)
	{
		this.r=r; //将r贯穿于整个类中
	}
	public String myReaderLine()throws IOException    //创建读行方法
	{
		LineNumber++;
		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 setLineNumber(int LineNumber)  //设置行方法
	{
		this.LineNumber=LineNumber;
	}
	public int getLineNumber()  //获取行方法
	{
		return LineNumber;
	}
	public void myclose()throws IOException
	{
		r.close();
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐