黑马程序员—IO输入输出流

1、IO流用来处理数据之间的传输
2、通过流的方式
3、操作流的对象存储于对象中
4、按操作的数据分为字符流和字节流,其中字节流融合了编码表
5、按流向分为输入流和输出流


IO流中的常用基类
1、字节流的抽象基类:InputStream和OutputStream
2、字符流中的抽象基类:Reader和Writer
以上四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
例如InputStream的子类FileInputStream,Reader的子类FileReader。


简单的IO字符流演示:

//简单的IO字符流与字节流演示:
import java.io.*;

class demo1
{
	public static void main(String[] args) throws IOException
	{
		FileWriter fw = new FileWriter("demo.txt");
		FileReader fr = new FileReader("demo.txt");	
		
		String buf = new String("黑马程序员,从这里出发!");
		fw.write(buf);
		fw.flush(); //这里必须要刷新下,否则数据都进行了缓冲区,没写进文件里
		
		int ch = 0;
		//reda()方法一次读取一个字节,并且会自动往下读,将字符作为一个整数返回,
		//如果读到末尾的话会返回-1	
		while((ch = fr.read())!=-1){ 
			System.out.println((char)ch);
		}
		fw.close();//关闭流资源,关闭的时候会自动刷新一下
		fr.close();
	}
}


字符流与字节流的区别主要在于字节流可以处理非文本数据的传输,

比如对图片或者音频这类文件的处理时就需要用到字节流了。

/*
复制一个图片
思路:
1、用字节读取流对象和图片关联
2、用字节写入流对象创建一个图片文件,用于存储获取到的图片数据
3、通过循环读写,完成数据的存储。
4、关闭资源
*/
import java.io.*;
class CopyPic
{
	public static void main(String[] args)
	{
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try
		{
			fos = new FileOutputStream("F:\\1234.jpg");
			fis = new FileInputStream("F:\\java\\day19\\123.jpg");
			
			byte []buf = new byte[1024];
			int len = 0;
			while((len=fis.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
		}
		catch(IOException e)
		{
			System.out.println(e);
			throw new RuntimeException("文件复制失败");
		}
		finally
		{
			try
			{
				if(fis!=null)
				fis.close();
			}
			catch(IOException e)
			{
			throw new RuntimeException("读取图片关闭失败");
			}
			try
			{
				if(fos!=null)
				fos.close();
			}
			catch(IOException e)
			{
			throw new RuntimeException("写入图片关闭失败");
			}
			
		}
	}
}


我们发现用流对象操作文件的时候,一次只能读一个字节,效率非常的低。

这时就引入了一个新的概念:缓冲区技术。从而也派生了两个新的类BufferedReader和BufferedWriter。

缓冲区技术的出现提高了对数据的读写效率。

缓冲区中提供了一些新的方法:

readLine(),该方法会根据换行符的位置,一次读取一行的数据,读到末尾的时候会返回null。

newLine(),写入一个行分隔符。

BufferedReader bufr = new BufferedReader(new FileReader("demo.txt")); //构造方法接收的是一个流对象。


模拟BufferedReader中的readLine方法

//通过自定义一个缓冲区的增强类来提升读的速度
class MyBufferedInputStream
{
	private InputStream in;
	private byte[] buf = new byte[1024*4];
	private int pos=0,count=0;//定义一个指针和计数器
	
	MyBufferedInputStream(InputStream in)
	{
		this.in = in;
	}
	//一次读一个字节,从缓冲区字节数组获取
	public int MyRead() throws IOException
	{
		//通过in对象读取硬盘上的数据并存储在buf中
		if(count==0)
		{
			pos = 0;
			count = in.read(buf);
			if(count<0)
				return -1;
			byte b = buf[pos];
			count--;
			pos++;
			return b&0xff;
		}
		else if(count>0)
		{
			byte b = buf[pos];
			count--;
			pos++;
			//byte类型在转换成int类型的时候会进行高位补位,导致高位全是1,
			//与上255,让其高位全是0,只保留最低8位。
			return b&0xff;
		}
		return -1;
	}


装饰设计模式:

IO流的缓冲技术就是一种装饰设计模式,当想要对已有的对象进行功能增强时,可以定义类,

将已有的对象传入,基于已有的功能,并提供加强功能,那么自定义的类就称为装饰类。

特点:装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰对象的功能,提供更强的功能。


装饰与继承的区别:

装饰模式比继承要灵活,避免了继承体系的臃肿,而且降低了子类与类之间的关系。

装饰类因为增强已有对象,具有的功能和已有的功能是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常都属于一个体系中的。


流对象使用的总结:

1、明确源和目的。

源:输入流。InputStream,Reader

目的:输出流。OutputStream,Writer

2、操作的是不是纯文本。

是:字符流

不是:字节流

3、当体系明确后,再明确要使用哪个具体的对象

通过设备来区分

源设备:内存,硬盘,键盘

目的设备:内存,硬盘,控制台


转换流:

InputStreamReader

OutputStreamWriter

在接收键盘录入并存储的时候,进行字节流和字符流的转换

BufferedReader bufr = new BufferedReader(new InputSreamReader(System.in));

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("dest.txt"),"utf-8"));//转换流可以将数据以指定的编码方式进行存储


转换流中可以改变输入输出的设备,例如上面的System.in。方法如下

System.setIn(InputStream in);

System.setOut(PrintStream out);




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值