黑马程序员——Java基础——IO(一)


------<a href=" http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------



一、IO流

要把数据逐一输出到某个设备中,或者从某个设备中逐一读取数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为IO流。Java对数据的操作是通过流的方式,用于操作流的对象都在IO包中。

流按流向分为:输入流和输出流。

流按操作数据分为两种:

字符流:抽象基类Reader,Writer。字符流只用于处理文字数据,原理是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。

字节流:抽象基类:InputStream,OutputStream。基本操作与字符流类相同。但它不仅可以操作字符,还可以操作其他媒体文件。

二、字符流

1.字符流的写入

import java.io.FileWriter;
import java.io.IOException;

public class WriterDemo {

	public static void main(String[] args) {
		
		//创建一个FileWriter对象并指定文件
		//该目录下有同名文件会被覆盖
		FileWriter fw = null;
		try
		{
			fw = new FileWriter("demo.txt");
			//往字符流中写入数据
			fw.write("java01");
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		//关闭资源,刷新流中缓冲的数据
		finally
		{
			try
			{
				if(fw!=null)
					fw.close();				
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			
		}		
	}

}


2.字符流的读取

import java.io.FileReader;
import java.io.IOException;

public class ReaderDemo {

	
	public static void main(String[] args) throws IOException   {


		read1();
		System.out.println("----------");
		read2();
	}	
	public static void read1() throws IOException
	{
		//创建FileReader对象,指定要读取的文件
		//如果不存在,会发生FileNotFoundException
		FileReader fr = new FileReader("demo.txt");
		
		//第一种读取方式,使用read()方法
		//每次读一个字符,并自动向下读取
		//读取到结尾返回-1
		int num = 0 ;
		while((num = fr.read())!=-1)
		{
			System.out.println((char)num);
		}
		fr.close();
	}
	public static void read2() throws IOException
	{
		//创建FileReader对象,指定要读取的文件
		//如果不存在,会发生FileNotFoundException
		FileReader fr = new FileReader("demo.txt");
		
		//第二种读取方式,使用int read(char[] cbuf,int off,int len)方法
		//创建一个字符数组,将读取到的字符先存入数组当中
		//返回读取的字符数,如果已到达流的末尾,则返回 -1 
		char [] ch = new char[1024];
		int num = 0 ;
		while((num = fr.read(ch))!=-1)
		{
			System.out.println(new String(ch,0,num));
		}
		fr.close();
	}
	
}

总结练习:复制文本文件

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyText {

	public static void main(String[] args) {
	
		FileWriter fw = null;
		FileReader fr = null;
		try {
			//创建字符写入流,指定目的地
			fw = new FileWriter("demo1.txt");
			//创建字符读取流,关联指定文件
			fr = new FileReader("./src/test/day4/MapDemo.java");
			//建立一个字符数组,临时存储读取流读取的数据,并使用写入流写入指定文件
			char[] ch = new char[1024];
			int num = 0;
			while ((num = fr.read(ch)) != -1) {
				fw.write(ch, 0, num);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fw != null)
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if (fr != null)
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

}


3.字符流的缓冲区

缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要先有流对象,作为参数传递给缓冲区的构造函数。

通过缓冲区复制文本文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


public class BufferedCopy {

	public static void main(String[] args) {
		//创建缓冲区,将文本写入字符输出流,缓冲各个字符
		//创建缓冲区,从字符输入流中读取文本,缓冲各个字符
		BufferedWriter bfw = null;
		BufferedReader bfr = null;
		try {
			//将需要提高效率的流对象作为参数传递给缓冲区的构造函数
			bfw = new BufferedWriter(new FileWriter("demo2.txt"));
			bfr = new BufferedReader(new FileReader("./src/test/day4/MapDemo.java"));
			//读取一个文本行将其写入流中,再写入一个行分隔符,需要刷新缓冲。
			String str = null;
			while((str = bfr.readLine()) != null)
			{
				bfw.write(str);
				bfw.newLine();
				bfw.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (bfw != null)
				try {
					bfw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if (bfr != null)
				try {
					bfr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}

}

明白了BufferedReader类中特有方法readLine的原理后,可以自定义一个类中包含一个功能和readLine一致的方法来模拟一下BufferedReader

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;


class MyBuffer extends Reader
{
	private Reader r ;
	MyBuffer(Reader r)
	{
		this.r = r ;
	}

	//模拟一个readLine方法
	public String myReadLine() throws IOException
	{
		//定义一个临时容量存储读到的每个字符并判断
		//因为每行结尾是\r\n,读到\r接着往下判断,读到\n就到了结尾
		StringBuilder sb = new StringBuilder();
		int num = 0 ;
		while((num = r.read())!=-1)
		{
			if(num == '\r')
				continue;
			if(num == '\n')
				return sb.toString();
			else
				sb.append((char)num);
		}
		if(sb.length()!=0)
			return sb.toString();
		return null;
		
	}
	//覆盖Reader中的抽象方法
	@Override
	public int read(char[] cbuf, int off, int len) throws IOException {
		// TODO Auto-generated method stub
		return r.read(cbuf, off, len);
	}

	@Override
	public void close() throws IOException {
		// TODO Auto-generated method stub
		r.close();
		
	}
	
}
public class MyBufferedReader {

	public static void main(String[] args) throws IOException {
		//使用自定义的缓冲区,过程与BufferedReader一样		
		MyBuffer mb = new MyBuffer(new FileReader("./src/test/day4/CollectionDemo.java"));
		String str = null;
		while((str = mb.myReadLine()) != null)
		{
			System.out.println(str);
		}
		mb.close();
	}

}

三、装饰设计模式

装饰模式是一种比较常见的模式,动态地给一个对象添加一些额外的职责。是对继承的有力补充,解决类膨胀的问题,降低类与类之间的耦合,具有非常好的扩展性。

//定义人的类,具有一个吃饭的方法
class Person
{
	public void eat()
	{
		System.out.println("吃饭");
	}
}
//定义西方人的类,用装饰的方式增强Person类
class Western
{
	private Person p ; 
	Western(Person p)
	{
		this.p = p;
	}
	public void eat()
	{
		System.out.println("开胃酒");
		p.eat();
		System.out.println("甜点");
	}
}
//定义中国人的类,用继承的方式增强Person类
class Chinese extends Person
{
	public void eat()
	{
		super.eat();
		System.out.println("喝汤");
	}
	
}


public class DecoratorDemo {

	public static void main(String[] args) {
		Person p = new Person();
		Western w = new Western(p);
		w.eat();
		
		System.out.println("-----------");
		
		Chinese c = new Chinese();
		c.eat();
	}

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值