黑马程序员_IO流

来源:互联网 发布:焊接仿真软件 编辑:程序博客网 时间:2024/05/17 13:09
------------- android培训java培训、java博客、java学习型技术博客、期待与您交流! -------------

IO流

概述java对数据的操作都是通过流的方式,而操作流的对象都封装在IO包中。凡是和设备发生数据关系的,几乎都有IOExcpetion。流的分类按数据流向不同可分为:输入流和输出流;按处理数据不同可分为:字节流和字符流;字节流一次读入或读出是一个字节即8位二进制,字符流一次读入或读出是一个字符即16位二进制(默认GBK解编码)。按实现功能不同可分为:节点流和处理流。节点流:能直接与数据源相连,实现读写;处理流:需与节点流一块使用,作用是增强节点流功能,实现更快更准确的读写。(装饰设计模式类)一览字符输入流(Reader)字符输出流(Writer)|--节点流类型|--节点流类型|--FileReader|--FileWriter|--PipedReader|--PipedWriter|--CharArrayReader|--CharArrayWriter|--处理流类型|--处理流类型|--BufferedReader|--BufferedWriter|--InputStreamReader|--OutputStreamWriter|--PrintWriter字节输入流(InputStream)字节输出流(OutputStream)|--节点流类型|--节点流类型|--FileInputStream|--FileOutputStream|--PipedInputStream|--PipedOutputStream|--ByteArrayInputStream|--ByteArrayOutputStream|--处理流类型|--处理流类型|--BufferedInputStream|--BufferedOutputStream|--DataInputStream|--DataOutputStream|--ObjectInputStream|--ObjectOutputStream|--SequenceInputStream|--PrintStream介绍Writer(写入字符流的抽象类)方法1、写入   write(int c) 写入单个字符,c为指定要写入字符的int, 写入的字符包含在给定整数值的16个低位中,另16高位被自动忽略   write(char[] cbuf) 写入字符数组   write(char[] cbuf,int off,int len) 写入字符数组的某一部分   write(String str) 写入字符串   write(String str,int off ,int len) 写入字符串的某一部分2、刷新   flush() 刷新该流的缓冲,写入字符流类通常需要刷新数据到目的地3、关闭   close() 关闭此流,但会先刷新它,另关闭的是与底层系统的链接并不是关闭对象Reader(读取字符流的抽象类)方法1、读取   int read()  读取单个字符,返回该字符的int,若读到该留末尾,则为-1。   int read(char[] cbuf)     cbuf为目标缓冲区,返回的int为读取的字符数,若到该流末尾,则为-1。2、关闭   close()InputStreamReader/OutputStreamWriter(转换流)前者是字节流通向字符流的桥梁,可使用指定字符集读取字节并将其解码为字符;后者是字符流通向字节流的桥梁,可使用指定字符集将要写入流中的字符编码成字节。构造方法InputStreamReader(InputStream in) 默认GBK码表InputStreamReader(InputStream in,String charsetName)OutputStreamWriter(OutputStream out) 默认GBK码表OutputStreamWriter(OutputStream out,String charsetName)子类FileReader 、 FileWriterFileReader/FileWriter(字符文件读取|写入流)写入/读取字符文件的便捷类构造方法字符读取/写入流对象一建立,就需要明确操作的文件FileReader(File file) |  FileReader(String fileName)FileWriter(File file) |  FileWriter(String fileName)对于后者,若文件不存在则会新建一个文件,若存在则会直接覆盖,如想续写,则写成:FileWriter(File file,true) |  FileWriter(String fileName,true)BufferedReader/BufferedWriter(字符读取|写入缓冲流)前者从字符输入流中读取文本,缓冲各个字符,从而实现高效读取;后者将文本写入字符输出流,缓冲各个字符,从而提供高效写入。原理该流内部封装数组缓冲区,将所读字符\或所写字符先存入数组,在一次读出或写入数组中字符构造方法BufferedReader(Reader in) | BufferedWriter(Writer out)特有方法String readLine() 读取一个文本行,通过'\r'和'\n'确认该行终止  返回包含该行内容的字符串,但不包含任何行终止符,若已到末尾,则返回nullnewLine() 因为读取一行方法不带行终止符,所以每写一行数据需要自动加行分隔符,  另该方法可跨平台性使用。BufferedReader 子类 LineNumberReader该缓冲字符输入流,提供了setLineNumber和getLineNumber两种方法,即可以带行号的输出数据原理:内部封装了int型lineNumber,每调用一次readLine方法,该值增1。InputStream/OutputStream(字节输入输出流)方法1、读取   int read() 从流中读取下一个字节,返回0-255内的int字节值,若到末尾则为-1;   int read(byte[] b) 读取一定数量字节并存储进缓冲区数组b中, 返回的int,为读取的字节数,若到末尾则返回-1.2、写入   write(byte[] b) 将byte数组中元素全部写入输出流   write(byte[] b,int off,int len), 将byte数组部分元素写入输出流中   write(int b) 将指定的字节写入此输出流,写入的的字节为b的八个低位另:字节流的写入可不用刷新。3、关闭close()FileInputStream/FileOutputStream(字节文件输入输出流)与字符文件输入输出流类似BufferedInputStream/BufferedOutputStream(字节输入输出缓冲流)功能类似字符输入输出缓冲流,但没有上述特有方法PrintStream/PrintWriter(打印输出/写入流)为其他输出流添加了功能,使它们能够方便打印各种数据值表示形式。特有功能1、该流内部对IO异常进行了处理,永远不会抛出IOException2、提供的打印方法,可以将各种类型数据都原样打印,同时可指定编码3、可自动刷新,可调用println方法以自动换行4、JDK1.5版本后,直接操作文件,构造方法PrintWriter(File file) || PrintWriter(String fileName)   直接操作文件PrintWriter(OutputStream out) 创建不带自动行刷新PrintWriter(OutputStream out,boolean autoFlush) 创建带自动行刷新,如果为true,则println、printf、format方法会自动刷新PrintStream 构造方法与上述一样,但PrintWriter多了接受Writer流的构造方法PrintWriter(Writer,out,boolean autoFlush)应用异常日志信息,可通过该流输入到文件,步骤:创建PrintStream并管理异常日志,catch数理代码中,调用printStackTrace(PrintStream ps)PipedInputStream/PipedOutputStream(字节管道流)PipedReader/PipedWriter(字符管道流)IO中涉及多线程技术的流概述将管道输出流与管道输入流连接以创建通信管道;输出流可往管道中写入数据,输入流可从管道中读取数据;因为输入和输出是同时进行,所以需用一个线程输出,一个线程输入。构造方法PipedOutputStream() 创建为连接到管道输入流的管道输出流这样构造,需要用到连接方法 connect(PipedInputStream snk)将它们连接PipedOutputStream(PipedInputStream snk) 连接snk的管道输出流字节输入管道流类似,字符管道流同理。ByteArrayInputStream/ByteArrayOutputStream(操作字节数组流)CharArrayReader/CharArrayWriter(操作字符数组流)概述操作的数据,为数组中数据,该数据存储位置是在内存中;内部封装了数组,作为缓冲区,没有调用底层资源,不会抛出IO异常;用流的思想操作数组。构造方法ByteArrayInputStream(byte[] buf)/ByteArrayInputStream(byte[] buf,int offset,int len)CharArrayReader(char[] buf)/CharArrayReader(char[] buf ,int offset,int length)其读取数据都为数组,且各自内部包含一个内部缓冲区,该缓冲区包含从流中读取的字节,内部计数器跟踪read方法要提供的下一个字节;从构造函数可以看出读取的是数组中数据,不用调用底层read,且不会抛异常,并不用关闭;ByteArrayOutputStream()CharArrayWriter()构造函数不用指定数据目的,因为它们内部封装了一个可变长度数组,调用write方法会将数据写入数组中,且会随着数据的不断增长而自动增长,可使用toByteArray()|toCharArray()和toString()获取数据特有方法writeTo(OutputStream out)  |  writeTo(Writer out)将数组输出流的全部内容写入到指定的输出流参数中toString() | toString(String charsetName)可使用指定charsetName,解码字节将缓冲区内容转换为字符串DataInputStream/DataOutputStream(数据输入输出流)概述专门用来操作基本数据类型的流;数据输出流可将Java基本数据类型数据局写入输出流中;数据输入流可从底层输入流中读取Java基本数据类型数据;不过输出的数据格式与读取数据的格式要一致,否则读不出来。构造方法DataInputStream(InputStream in) | DataOutputStream(OutputStream out)ObjectInputStream/ObjectOutputStream(对象操作流)概述后者可以将Java对象的基本数据类型和图形写入该流中,称为对象的序列化;前者可将后者写入的基本数据和对象进行反序列化;对象在程序运行时,是存储于堆内存的,随着程序结束,该对象也消失了,所以可借助两者与字节文件输入输出流一起使用来实现对象的持久存储;另被操作的对象必须是实现了Serializable接口的对象。构造方法ObjectInputStream(InputStream in)ObjectOutputStream(OutputStream out)读取/写入对象方法Object readObject() 从InputStream流中读取对象writeObject(Object obj) 将对象写入到OutputStream流中注意静态成员不能被序列化,因为其不再堆内存中;使用transient关键字可使非静态的数据不被序列化SequenceInputStream(序列流)概述它表示其它输入流的逻辑串联,所涉及输入流用有序集合进行封装,它从第一个输入流开始,依次读取到最后一个输入流末尾为止;它实现了多个数据的合并。构造方法两个流的连接SequenceInputStream(InputStream s1,InputStream s2)多个流的连接SequenceInputStream(Enumeration<? extends InputStream> e)参数必须是运行生成类型为InputStream对象的Enumeration型参数参数Enumeration<? extends InputStream e>1、用Vector封装流对象,然后通过elments()方法获取该接口对象;2、用ArrayList封装流对象,后建立Enumeration匿名内部类用迭代器中的hasNext()和Next()方法分别复写枚举接口中的hasMoreElements()和nextElement()示例ArrayList<InputStream> al = new ArrayList<InputStream>();Iterator<InputStream> it = al.iterator();SequenceInputStream sis = new SequenceInputStream(new Enumeration<InputStream>(){public boolean hasMoreElements(){return it.hasNext();}public InputStream nextElement(){return it.next();}});RandomAccessFile(随机访问文件)概述该类不算是IO体系中子类,而是直接继承自Object,但是它是IO包中成员,因为它具备读和写功能内部封装了一个数组,而且通过指针对数组的元素进行操作可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置  其实完成读写的原理就是内部封装了字节输入和输出流构造方法RandomAccessFile(File file,String mode)RandomAccessFile(String name,String mode)通过构造函数可以看出该类只能操作文件而且操作文件还有模式,r、rw、rws、rwd四种模式如果模式为r,不会创建文件,会去读取一个已存在文件,如果该文件不存在则会出现异常如果模式为rw,操作的文件不存在,则自动创建,如果存在则不会覆盖方法随机访问文件,自身具备读写的方法,通过skipBytes(int x)、seek(int x)来达到随机访问注意skipBytes()方法指正不能往回跳;流输入输出数据都是从头到尾开始按照顺序执行,但是该类可以自定义读取位置,也可以指定位置添加写入值,所以就可以实现数据的分段写入,从而可以为每段数据分配一个线程进行写入,如多个线程下载数据模式就是这个道理。

源和目的

概述IO流中对象操作的是数据,数据的来源及数据去向分为以下几种;源:  内存、硬盘和键盘目的:内存,硬盘和控制台内存临时数据,如操作字节或字符数组流操作的数组对象就是存储在内存中。键盘和控制台控制台即将数据输出至屏幕:  InputStream in = System.in;键盘即通过键盘来录入数据; PrintStream out = System.out;硬盘持久化存储的数据,一般以File形式存在,因为流只能操作数据,Java中File类将文件或文件夹封装成对象,以方便操作这些对象。File构造方法File(String pathName)File(String parent,String child)File(File parent,String child)方法1、创建boolean createNewFile()在指定位置创建文件,如果该文件已经存在,则不创建,返回false和输出流不一样,输出流对象一建立就创建文件,而且若文件已经存在则会覆盖boolean mkdir() 创建文件夹,只能创建一级文件夹boolean mkdirs() 创建多级文件夹2、删除boolean delete() 删除失败返回falsevoid deleteOnExit() 在程序退出时删除指定文件3、判断boolean exists() 文件是否存在isFile()判断是否文件isDirectory()判断是否为文件目录isHiden()   判断文件是否隐藏文件isAboslute()判断文件路径是否是绝对路径名4、获取String getName()返回文件名String getPath()返回文件路径,构建时候指定的是什么返回什么String getParent()返回父目录的路径名字,若没指定,则返回nullString getAbsoultePath()  返回文件绝对路径long lastModified()  返回最后一次被修改的时间long length();    返回文件大小,以字节为单位5、重要方法String[] list();返回一个字符串数组,它为目录中的文件和目录String[] list(FilenameFilter filter)返回满足指定过滤器的文件和目录的字符串数组File[] listFiles()返回抽象路径名数组File[] listFiles(FilenameFilter filter)返回满足指定过滤器的文件和目录的抽象路径名数组一般用后者,因为返回的File[]还可被File对象方法操作。FilenameFilter 接口,可用于过滤某些文件名,接口方法只有:boolean accept(File dir,String name) dir 文件目录 name 文件名称返回true就保留,返回假就舍弃,e.gnew FilenameFilter(){public boolean accept(File dir,String name){return name.endsWith(".java");}}dir中文件名不是以.java结尾的文件会被过滤掉

其他相关类

System方法InputStream in = System.in;PrintStream out = System.out;static void setIn(InputStream in) 重新分配"标准"输入流static void setOut(OutputStream out) 重新分配"标准"输出流Properties extends HashTable<Object,Object>概述该类表示了一个持久的属性集,可保存在流中或从流中加载;它的属性列表中每个键及其对应值都是一个字符串,因而不需要泛型;它可以加载流直接读取键盘中文件里的键值对信息,而且还可以修改键值对匹配值且保存在原有文件中;它是集合中与IO技术相结合的集合容器。方法1、添加键值对,Object setProperty(String key,String value)调用HashTable的put方法,强制添加的键值为字符串,返回为指定键的旧址,若没有则null2、读取String getProperty(String key) 获取该键的值,若没有则为nullSet<String> stringPropetryNames() 返回属性列表中键集Enumeration<?> propertyNames() 返回属性列表中键的枚举3、加载字节流(1.2版本)、加载字符流(1.6版本)load(InputStream in) 从输入流中读取属性列表load(Reader r) 按简单的面向行的格式从字符读取流中读取属性列表4、写入字节流(1.2版本)、写入字符流(1.6版本)Store(OutputStream out,String comments)  将适合格式将属性列表写入输出流Store(Writer wrieter,String comments)  以适合格式将属性裂隙写入输出流   comments 代表注释

其它

装饰设计模式当想要对已有的对象进行功能增强时,可定义类,将已有对象传入,基于已有的功能,并提供加强功能,该类就称为装饰类装饰类通常会通过构造方法接受被装饰对象,并基于被装饰的对象的功能,提供更强的功能;IO中处理流基本都是运用装饰设计模式产生的类。见如下自定缓冲字符读取流示例class MyBufferedReader extends Reader{private Reader r ;MyBufferedReader(Reader r){this.r = r;}public String readLine()throws IOException{StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1){if (ch=='\r')continue;else if(ch=='\n')return sb.toString();elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public void close() throws IOException{r.close();}public int read(char[] cbuf,int off,int len)throws IOException{return r.read(cbuf,off,len);}}递归其实就是函数自身内部调用自身方法。递归就是在栈内存中不断的加载同一个函数。应用当一个功能被重复使用,而每一次使用该功能时的参数不确定,都由上次的功能元素结果来确定。功能内部又用到该功能,但是传递的参数值不确定。(每次功能参与运算的未知内容不确定)。注意事项1:一定要定义递归的条件;2:递归的次数不要过多,容易出现 StackOverflowError 栈内存溢出错误。示例将毕向东java基础文件夹中文件夹+文件名的相对路径名写入当前java.txt中import java.io.*;class Demo5{public static void main(String[] args){for (int x=1;x<26 ;x++ ){File dir = new File("c:\\java\\毕向东Java基础\\第"+x+"天");method(dir);}}public static void method(File dir){BufferedWriter bfw = null;try{bfw = new BufferedWriter(new FileWriter("java.txt",true));bfw.write(dir.getName());bfw.newLine();File[] files = dir.listFiles();for (int x=0;x<files.length;x++){if (files[x].isDirectory())method(files[x]); //此处递归else{bfw.write("  "+files[x].getName());bfw.flush();bfw.newLine();}}}catch (IOException e1){throw new RuntimeException("failed to write");}finally{try{if(bfw!=null)bfw.close();}catch (IOException e2){}}}}
------------- android培训java培训、java博客、java学习型技术博客、期待与您交流! -------------
详情请查看:http://edu.csdn.net/heima/
0 0