黑马程序员_IO流(一)

------- android培训java培训、期待与您交流! ----------
IO流(Input&Output Stream)
IO流用来处理设备间的数据传输,Java语言用IO流技术来处理设备上已有的数据(包括硬盘文件,内存中的数据等),java 用于操作流的对象都存放在IO包中(java.io.*)。
流按照流向分为:输入流输出流
按照操作数据分为:字节流字符流
早期计算机操作数据都使用字符流,因为数据在计算机中都是以二进制存在的。而文本数据在数据操作中是很常见的,为了方便操作文本数据,单独分离出字符流,字符流在内部融合了编码表,字符流基于字节流
IO流常用的基类
IO体系中一共有四个基类
字节流的抽象基类:
InputStreamOutputStream
字符流的抽象基类
ReaderWriter 
这四个基类都是抽象的,类中有抽象的方法,由其子类来实现,由这四个基类派生出来的子类都是以其父名作为类名的后缀  
字符流
I O 流逝操作数据的,数据最常见的表现形式是文件
Writer 写入字符流的抽象类,操作文件的子类是FileWriter ,用来写入文件的便捷类。
FileWriter 构造方法:
FileWriter(File file)
          根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(String fileName)
          根据给定的文件名构造一个 FileWriter 对象。
该流对象一被创建就要有被操作的文件存在
常用方法:
write(String str)    写入字符串
write(int c) 写入单个字符。
write(char[] cbuf)  写入字符数组。
flush() 刷新该流的缓冲。
close()  关闭此流,但要先刷新它。
import java.io.*;//第一步,导入io包
class  FileWriterDemo
{
	public static void main(String[] args) throws Exception//将异常抛出
	{

		FileWriter fw=new FileWriter("demo.txt");//第二步,创建对象并初始化对象(明确文件存放目的地)
		fw.write("abcde");//第三步,调用write方法将字符串写入到流中
		fw.flush();//第四步,刷新流对象缓冲中的数据,将数据刷新到目的地中
		//fw.close();//关闭流资源,关闭前会刷新内部缓冲区的数据,将数据刷到目的地中,刷新后将流关闭
		//flush 与close 区别,都会刷新缓冲区的数据将数据刷到目的地,刷新后,flush 不关闭流流可以继续写入,close 关闭流
	}
}
IO 异常的处理方式
对抛出异常的语句进行try catch 处理
class FileWriterDemo2 
{
	public static void main(String[] args) 
	{
		FileWriter fw = null;//方便调用close ,将fw定义在try代码块外
		try
		{
			fw = new FileWriter("demo.txt");//会抛出异常
			fw.write("abcdekkkk");//会抛出异常
		}
		catch (IOException e)
		{
			System.out.println(e.toString());//异常处理语句

		}
		finally
		{
			try
			{
				if(fw!=null)//判断fw是否为空,如果不是null就关闭流,提高代码健壮性
				fw.close();//关闭资源
			}
			catch (IOException e)
			{
				System.out.println(e.toString());
			}
			
		}
			
	}
}
FileReader
构造方法
FileReader(File file)
          在给定从中读取数据的 File 的情况下创建一个新 FileReader
FileReader(String fileName)
          在给定从中读取数据的文件名的情况下创建一个新 FileReader
一构造的时候就要指定文件
常用的方法
read()
          读取单个字符。//作为整数读取的字符,如果已到达流的末尾,则返回 -1
read(char[] cbuf)
          将字符读入数组。//读取的字符数,如果已到达流的末尾,则返回 -1
close()
          关闭该流并释放与之关联的所有资源。
字符流读取方式一
import java.io.*;
class FileReaderDemo1 
{
	public static void main(String[] args) throws Exception//记得会发生异常,对异常处理
	{
		FileReader fr=new FileReader("demo.txt");//创建read流对象与已经存在的文本文件相关联//!!!!!加双引号
		//如果文件不存在会发生FileNotFoundException
		int ch=0;
		while((ch=fr.read())!=-1)//括号括号!!!!
		{
			System.out.print((char)ch);//将int型强转成char型
			
		}
		fr.close();//关闭流
		//fr.read()//调用读取流的read方法读取一个字符
	}
}
字符流读取方式二
用read(char[])将字符存入数组,(返回数组中字符个数),将数组转换成字符串,获取数据
import java.io.*;
import java.util.*;
class  FileReaderDemo2
{
	public static void main(String[] args) throws Exception
	{
		FileReader fr=new FileReader("demo.txt");
		char[] arr=new char[1024];//通常定义1024
		int ch=0;
		while((ch=fr.read(arr))!=-1)//将数据存入数组
		{
		//	System.out.println("num="+ch+Arrays.toString(arr,0,num));//Arrays 的toString方法将数组转换为字符串
		System.out.println("num="+ch+"````"+new String(arr,0,ch));//获取数组中从0角标开始的ch个字符
		}
		fr.close();//循环结束要关闭流
	}
}
字符流缓冲区
IO流在读写中需要提高读写效率,读写效率的提高有助于优化程序,缓冲区要结合流使用,在流的基础上对流的功能进行增强
对应类
BufferedWriter:

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 

构造方法
BufferedWriter(Writer out)
          创建一个使用默认大小输出缓冲区的缓冲字符输出流
特有方法
newLine() 写入一个行分隔符。是一个跨平台的换行符
//创建一个流字符写入对象
		FileWriter fw=new FileWriter("buf.txt");
		//提高流写入效率,加入缓冲技术,将流对象作为参
		//数传递给缓冲区的构造函数
		BufferedWriter bufw=new BufferedWriter(fw);
		for(int i=0;i<5;i++)
		{
			bufw.write("abcde");
			//缓冲区中提供跨平台换行操作:newLine ()
			bufw.newLine();//写入换行分隔符
			//用到缓冲区就要用刷新
			bufw.flush();
		}
		//关闭缓冲区就是关闭缓冲区中的流对象,所以流对象的close 不用写 
		bufw.close();
BufferedReader 
构造方法
FileReader(File file)
          在给定从中读取数据的 File 的情况下创建一个新 FileReader
FileReader(String fileName)
          在给定从中读取数据的文件名的情况下创建一个新 FileReader
特有方法
readLine()  读取一个文本行。返回String类型
//创建流读取对象与文件相关联
		FileReader fr=new FileReader("buf.txt");
		//创建缓冲区,将字符读取流对象传递给缓冲区的构造函数
		BufferedReader bufr=new BufferedReader(fr);
		String line=null;
		while((line=bufr.readLine())!=null)//readLine()是缓冲区的方法
		{
			System.out.println(line);
		}
ReadLine()方法的原理
无论是读一行还是读取多个字符,都是在硬盘一个一个的读取最终使用Read ()方法一次读取一个
装饰设计模式
当想对已有对象进行功能增强时,定义一个类,将已有对象传入,基于已有的功能,提供加强功能,那么定义的类称为装饰类。
装饰类会通过构造方法接收已有的被装饰对象,并基于被装饰类对象的功能,提供更强的功能
装饰设计模式与继承
和继承相比,装饰设计模式更灵活,避免了体系的臃肿,降低了类之间的关系
装饰类示例:
import java.io.*;
class MyBufferedReader//定义一个装饰类
{
	private FileReader r;
	MyBufferedReader(FileReader r)//构造函数中传入被装饰的对象
	{
		this.r=r;
	}
	public String MyreadLine() throws IOException//基于read()方法,定义MyreadLine方法实现读取一行的功能
	{
		StringBuffer sb=new StringBuffer();
		int ch=0;
		while((ch=r.read())!=-1)
		{
			if(ch=='\r')//如果读到‘r’
				continue;//继续
			if(ch=='\n')//如果读到‘n’
			return sb.toString();//字符串形式返回读取到并存入缓冲区的数据
			else 
			sb.append((char)ch);//否则向缓冲区添加字符
		}
		//if (sb!=null)条件错误
		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 mbfr=new MyBufferedReader(fr);//创建自定义缓冲区
		String line=null;
		while((line=mbfr.MyreadLine())!=null)//调用MyreadLine方法,读取一行数据
		{
			System.out.println(line);
		}
		mbfr.MyClose();//关闭流

	}
}
LineNumberReader 
LineNumberReader 是BufferedReader 的子类,跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) getLineNumber() ,它们可分别用于设置和获取当前行号。
构造方法
LineNumberReader(Reader in)
          使用默认输入缓冲区的大小创建新的行编号 reader。
特有方法
setLineNumber(int lineNumber) 设置当前行号。
getLineNumber() 获得当前行号。
public static void main(String[] args) throws Exception
	{
		FileReader fr=new FileReader("BufferRWTest.java");
		LineNumberReader lnr=new LineNumberReader(fr);
		String 	line=null;
		lnr.setLineNumber(20);//设置行号,从第21 行开始打印
		while ((line=lnr.readLine())!=null)
		{
			System.out.println(lnr.getLineNumber()+":"+line);//获取行号
		}

	}
字节流
要操作图片数据就要用到字节流,图片是文件,就要使用字节流中操作文件的子类  
FileOutputStream
构造方法
FileOutputStream(File file)
          创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name)
          创建一个向具有指定名称的文件中写入数据的输出文件流。
常用方法
write(byte[] b)     将b.length 个字节从指定 byte 数组写入此文件输出流中。
write(int b)  将指定字节写入此文件输出流

代码示例
public static void write() throws IOException//写入文件
	{
		FileOutputStream fos=new FileOutputStream("fos.txt");
		fos.write("abcdefg".getBytes());//这个write方法的参数为byte型 需要将String类型转换成byte型,用getBytes()方法
		fos.close();//关闭流
注意:字符流底层使用的是字节流的数组缓冲区,将读取到的字节临时存储,再查找编码表,获取字符,需要将字符刷新到目的地,字节流可以直接输入数据,不需要刷新,所以没有Flush 方法。
FileInputStream
构造方法
FileInputStream(File file)
          通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象file 指定。
FileInputStream(String name)
          通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
常用方法
read()  从此输入流中读取一个数据字节。
read(byte[] b)   从此输入流中将最多b.length 个字节的数据读入一个 byte 数组中。
close()  关闭此文件输入流并释放与此流有关的所有系统资源。
available()  返回文件的字符数,可以用来定义刚刚好的字符数组缓冲区。
字节流读取方式一:
用Read()方法读取文件字节
public static void read_1() throws IOException//读取文件fos.txt 数据方法一
	{
		FileInputStream  fis=new FileInputStream("fos.txt");
		int ch=0;
		while ((ch=fis.read())!=-1)
		{
			System.out.print((char)ch);
		}
		fis.close();//关闭资源
	}
字节流读取方式二
用Read(bytes[] buf) 方法将文件读取到缓冲区数组中
public static void read_2() throws IOException
	{
		FileInputStream fis=new FileInputStream("fos.txt");
		int ch=0;
		byte[] b=new byte[1024];//定义1024 长度的字节数组
		while ((ch=fis.read(b))!=-1)
		{
			//System.out.println(b.toString());//打印的是引用地址,不对!
			System.out.println(new String(b,0,ch));//new 字符串对象,byte数组直接作为参数传进去,从0角标开始,打印ch个
		}
		fis.close();
        }
字节流读取方式三
用available()方法定义大小刚好的字节数组缓冲区,将文件读到缓冲区
public static void read_3() throws IOException//如果文件过大,慎用此方法,因为如果数据过大,
												//需创建一个相当的字节数组,内存可能会溢出
	{
		FileInputStream fis=new FileInputStream("fos.txt");
		//int ch=0;
		byte[] b=new byte[fis.available()];//定义一个长度刚好的缓冲区
		//因为已知长度了就不需要在循环了 
		fis.read(b);
		System.out.println(new String (b));

	}

字节流的缓冲区
IO字节流在读写操作中,为了提高效率,用到字节流缓冲区,该缓冲区封装了缓冲数组,因此直接调用读写方法即可,而不需要定义缓冲区
代码示例:用字节流缓冲区复制。MP3文件
public static void copy_1() throws IOException
	{
		BufferedInputStream bis=new BufferedInputStream(new FileInputStream("周杰伦 - 稻香.mp3"));
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("稻香2.mp3"));
		int ch=0;//字节的数值数值
		while ((ch=bis.read())!=-1)
		{
			bos.write(ch);
		}
		//关闭资源
		bis.close();
		bos.close();
	}
------- android培训java培训、期待与您交流! ----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值