黑马程序员_IO流概述

---------------------- <a href="http://edu.youkuaiyun.com"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.youkuaiyun.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

 一、IO流的作用

IO流用来处理设备之间的数据传输,比如查看图片、播放歌曲、拷贝文件等操作。

l Java 对数据的操作是通过流的方式,Java用于操作流的对象都在IO(InputOutput) 包中。
l 流按操作数据分为两种:字节流与字符流
字节流可以操作所有数据类型,包括歌曲、图片、电影、文本等。因为这些数据在计算机中的存储方式都是转换为二进制表现形式。
字符流可以操作文本数据,因为不同国家的文字编码不同,可以用字符流中的转换流将文本以指定的编码格式写入和读取。
l 流按流向分为:输入流输出流
二、IO流常用基类和子类
l 字节流的抽象基类: InputStreamOutputStream 。其对应的子类如下图所示:
l 字符流的抽象基类: ReaderWriter 。其对应的子类如下图所示:
l
注:由这四个抽象基类派生出来的子类名称都是以其父类名作为子类名的后缀。

三、字符流的使用

字符读取流的常用方法:

int read():读取单个字符。

int read(char[] cbuf):将字符读入数组。

abstract void close():关闭该流并释放与之关联的所有资源。

通过下面的代码演示字符读取流的操作:

package demo4;
import java.io.*;
/*
演示读取指定的文件
*/

class FileReaderDemo 
{
	public static void main(String[] args) throws IOException
	{
		//创建一个文件读取流对象,和指定名称的文件相关联
		//要保证该文件是已经存在的,如果不存在,会发生异常:FileNotFoundException
		FileReader fr=new FileReader("demo1.txt");
		
		//调用读取流对象的read方法
		//read():一次读一个字符,而且会自动往下读
		//返回读取到的字符的ASCII码值
		//int ch=fr.read();

		int ch=0;
		while((ch=fr.read())!=-1)
		{
			System.out.print((char)ch);
		}

		//关闭该流并释放与之关联的所有资源。
		fr.close();
	}
}
字符输出流的常用方法:

void write(char[] cbuf):写入字符数组。

abstract void write(char[] cbuf,int off,int len):写入字符数组的某一部分。

void write(int c):写入单个字符。

abstract void flush():刷新该流的缓冲。如果不刷新的话,保存在字符数组中的数据会被覆盖。

abstract void close():关闭此流,但要先刷新它。

下面通过一个示例演示字符输出流的操作:

package demo1;
import java.io.*;
/*
需求:在硬盘上,创建一个文件并写入一些文字数据。
找到一个专门用于操作文件的Writer子类对象:FileWriter。
后缀名是父类名,前缀名是该流对象的功能。
*/

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

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

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

		//关闭流资源,但是关闭之前会刷新一次内部缓冲中的数据。
		//将数据刷到目的地中。
		//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
		fw.close();
	}
}

四、字符流的缓冲区

缓冲区的出现提高了对数据的读写效率。将数据读取或写入到缓冲区中,然后一次性写入或者读取出来。

对应类:

BufferedWriter:字符写入流缓冲区。

该缓冲区中提供了一个跨平台的换行方法:newLine()。
BufferedReader:字符读取流缓冲区。

该缓冲区提供了一个一次读一行的方法:readLine(),方便于对文本数据的读取。当返回null时,表示读到文件末尾。

l 注意:缓冲区要结合流才可以使用。 在流的基础上对流的功能进行了增强。
五、字节流的使用
字节读取流的常用方法:
abstract int read():从输入流中读取数据的下一个字节。
int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
int read(byte[] b,int off,int len):将输入流中最多len个数据字节读入byte数组。
void close():关闭此输入流并释放与该流关联的所有系统资源。
字节写入流的常用方法:
void write(byte[] b):将b.length个字节从指定的byte数组写入此输出流。
void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此输出流。
void close():关闭此输出流并释放与此流有关的所有系统资源。
代码演示:
package demo1;
import java.io.*;
/*
字节流:InputStream   OutputStream

需求:想要操作图片数据,这时就要用到字节流。
*/


class FileStreamDemo 
{
	public static void fileWriter()throws IOException
	{
		//创建字节写入流对象,并指定文件的名称和路径
		FileOutputStream fos=new FileOutputStream("demo1.txt");
		//向指定文件中写入数据
		//由于只能写入字节类型,所以要转换一下
		fos.write("abcedfg".getBytes());
		//关闭字节写入流
		fos.close();
	}

	public static void fileReader_1()throws IOException
	{
		//创建字节读取流对象,并和指定名称的文件相关联
		FileInputStream fis=new FileInputStream("demo1.txt");
		//从指定文件中读取数据
		int num=0;
		//一次读取一个字节
		while((num=fis.read())!=-1)
		{
			System.out.println((char)num);
		}
		//关闭流并释放与之关联的所有资源
		fis.close();
	}

	public static void fileReader_2()throws IOException
	{
		FileInputStream fis=new FileInputStream("demo1.txt");
		int num=0;
		//把读取到的数据临时存放到缓冲区中(byte[])
		byte[] b=new byte[1024];
		while((num=fis.read(b))!=-1)
		{
			System.out.println(new String(b,0,num));
		}
		fis.close();
	}

	public static void fileReader_3()throws IOException
	{
		FileInputStream fis=new FileInputStream("demo1.txt");
		//返回下一次对此输入流调用的方法可以不受阻塞地
		//从此输入流读取(或跳过)的估计剩余字节数。
		//通俗来讲,就是得到文件中的字节数。
		//int len=fis.available();
		//System.out.println(len);
		//定义一个长度与文件字节数刚刚好的字节数组
		//切记:文件字节数不可过大,否则内存溢出异常!
		//java虚拟机默认占用内存空间64MB!
		byte[] b=new byte[fis.available()];
		//既然长度刚刚好,那就不用循环了,一次性读完
		fis.read(b);
		System.out.println(new String(b));

		fis.close();
	}

	public static void main(String[] args) throws IOException
	{
		//fileWriter();
		//fileReader_1();
		//fileReader_2();
		fileReader_3();
	}
}
六、字节流的缓冲区
同字符流的缓冲区一样,也是为了提高对数据的读写效率。将数据读取或写入到缓冲区中,然后一次性写入或者读取出来。
对应类:
BufferedInputStream:字节读取流缓冲区。
BufferedOutputStream:字节输出流缓冲区。
通过对歌曲的复制操作演示字节流缓冲区的使用:
public static void copy()
	{
		BufferedInputStream bufis=null;
		BufferedOutputStream bufos=null;
		try
		{
			//创建字节读取流缓冲区对象,
			//并把字节读取流对象当做参数传递给字节读取流缓冲区对象的构造函数
			bufis=new BufferedInputStream(new FileInputStream("Before - Moderndog.mp3"));
			//创建字节写入流缓冲区对象,
			//并把字节写入流对象当做参数传递给字节写入流缓冲区对象的构造函数
			bufos=new BufferedOutputStream(new FileOutputStream("Before - Moderndog_copy.mp3"));

			int by=0;
			//循环 读取单个字节
			while((by=bufis.read())!=-1)
			{
				//循环 将指定的字节写入此缓冲的输出流。
				bufos.write(by);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("赋值MP3失败!");
		}
		finally
		{
			try
			{
				if(bufis!=null)
					bufis.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("字节读取流关闭失败!");
			}
			try
			{
				if(bufos!=null)
					bufos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("字节写入流关闭失败!");
			}
		}
	}
七、转换流
可以将字节流对象转换成字符流对象。
转换流的两个对象:
InputStreamReader:将字节读取流对象转换成字符读取流对象。
OutputStreamWriter:将字节写入流对象转换成字符写入流对象。
转换流的作用:
方便了字符流与字节流之间的操作,是字符流与字节流之间的桥梁。当字节流中的数据都是字符时,转成字符流操作更高效。

八、标准输入输出流

l System类中的字段:in、out, 它们各代表了系统标准的输入和输出设备。
System.out:对应的是标准输出设备:控制台。
System.in:对应的是标准输入设备:键盘。
l System.in的类型是 InputStream。
l System.out的类型是PrintStream,OutputStream的子FilterOutputStream的子类。
九、IO包中的其它类
l RandomAccessFile: 随机访问文件,自身具备读写的方法。
通过skipBytes(int x),seek(int x) 来达到随机访问。
l 管道流: PipedInputStreamPipedOutputStream
输入输出可以直接进行连接,通过结合线程使用。
l 打印流: PrintWriterPrintStream
可以直接操作输入流和文件。
l 序列流: SequenceInputStream
对多个流进行合并。
l 操作对象: ObjectInputStreamObjectOutputStream
被操作的对象需要实现Serializable(标记接口 )。
l 操作基本数据类型: DataInputStreamDataOutputStream
l 操作字节数组: ByteArrayInputStreamByteArrayOutputStream
l 操作字符数组: CharArrayReaderCharArrayWriter
l 操作字符串: StringReader StringWriter
---------------------- <a href=" http://edu.youkuaiyun.com"target="blank">ASP.Net+Android+IOS 开发</a>、<a href=" http://edu.youkuaiyun.com"target="blank">.Net 培训</a>、期待与您交流! ----------------------

详细请查看:<a href="http://edu.youkuaiyun.com" target="blank">http://edu.youkuaiyun.com</a>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值