黑马程序员_IO流(一)

来源:互联网 发布:网络培训机构北京 编辑:程序博客网 时间:2024/05/14 09:40
------- android培训、java培训、期待与您交流! ----------
IO流(Input&Output Stream)
IO流用来处理设备间的数据传输,Java语言用IO流技术来处理设备上已有的数据(包括硬盘文件,内存中的数据等),java 用于操作流的对象都存放在IO包中(java.io.*)。
流按照流向分为:输入流输出流
按照操作数据分为:字节流字符流
早期计算机操作数据都使用字符流,因为数据在计算机中都是以二进制存在的。而文本数据在数据操作中是很常见的,为了方便操作文本数据,单独分离出字符流,字符流在内部融合了编码表,字符流基于字节流
IO流常用的基类
IO体系中一共有四个基类
字节流的抽象基类:
InputStreamOutputStream
字符流的抽象基类
ReaderWriter 
这四个基类都是抽象的,类中有抽象的方法,由其子类来实现,由这四个基类派生出来的子类都是以其父名作为类名的后缀  
字符流
IO 流逝操作数据的,数据最常见的表现形式是文件
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流对象与已经存在的文本文件相关联//!!!!!加双引号//如果文件不存在会发生FileNotFoundExceptionint 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];//通常定义1024int 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培训、期待与您交流! ----------

0 0
原创粉丝点击