黑马程序员---IO流后半部分总结

来源:互联网 发布:蚂蚁网络电视官方下载 编辑:程序博客网 时间:2024/05/01 03:58
---------------------- android培训、java培训、期待与您交流! ----------------------

                      

字符流:

Reader用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) close()

     |---BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

        |---LineNumberReader跟踪行号的缓冲字符输入流。此类定义了方法setLineNumber(int)getLineNumber(),它们可分别用于设置和获取当前行号。

     |---InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

        |---FileReader用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader

     |---CharArrayReader

     |---StringReader

-------------------------------------------------

Writer写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)flush() close()

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

     |---OutputStreamWriter是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

        |---FileWriter用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter

     |---PrintWriter

     |---CharArrayWriter

     |---StringWriter

------------------------------------------------------------------------------

字节流:

InputStream是表示字节输入流的所有类的超类。

     |--- FileInputStream从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。FileInputStream用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader

     |---FilterInputStream包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。

        |--- BufferedInputStream

        |--- Stream

     |---ObjectInputStream

     |---PipedInputStream

-----------------------------------------------

OutputStream此抽象类是表示输出字节流的所有类的超类。

     |---FileOutputStream文件输出流是用于将数据写入FileFileDescriptor的输出流。

     |---FilterOutputStream此类是过滤输出流的所有类的超类。

        |---BufferedOutputStream该类实现缓冲的输出流。

        |--- PrintStream

        |--- DataOutputStream

     |---ObjectOutputStream

     |---PipedOutputStream

------------------------------------------------------------------------------

File类:

将文件系统中的文件和文件夹封装成了对象。

提供了更多的属性和行为可以对这些文件和文件夹进行操作。

这些是流对象办不到的,因为流只操作数据。

 

File类常见方法:

 

1:创建。

    boolean createNewFile():在指定目录下创建文件,如果该文件已存在,则不创建。

而对操作文件的输出流而言,输出流对象已建立,就会创建文件,如果文件已存在,会覆盖。除非续写。

    boolean mkdir():创建此抽象路径名指定的目录。

    boolean mkdirs():创建多级目录。

 

2:删除。

    boolean delete():删除此抽象路径名表示的文件或目录。

    void deleteOnExit():在虚拟机退出时删除。

注意:在删除文件夹时,必须保证这个文件夹中没有任何内容,才可以将该文件夹用delete删除。

    window的删除动作,是从里往外删。

    注意:java删除文件不走回收站。要慎用。

 

3:获取.

    long length():获取文件大小。

    String getName():返回由此抽象路径名表示的文件或目录的名称。

    String getPath():将此抽象路径名转换为一个路径名字符串。

    String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。

    String getParent():返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回null

long lastModified():返回此抽象路径名表示的文件最后一次被修改的时间。

File.pathSeparator:返回当前系统默认的路径分隔符,windows默认为“;”。

File.Separator:返回当前系统默认的目录分隔符,windows默认为“\”。

 

4:判断:

    boolean exists():判断文件或者文件夹是否存在。

    boolean isDirectory():测试此抽象路径名表示的文件是否是一个目录。

    boolean isFile():测试此抽象路径名表示的文件是否是一个标准文件。

    boolean isHidden():测试此抽象路径名指定的文件是否是一个隐藏文件。

    boolean isAbsolute():测试此抽象路径名是否为绝对路径名。

 

5:重命名。

     boolean renameTo(File dest):可以实现移动的效果。剪切+重命名

 

String[] list():列出指定目录下的当前的文件和文件夹的名称。包含隐藏文件。

 

如果调用list方法的File 对象中封装的是一个文件,那么list方法返回数组为null。

如果封装的对象不存在也会返回null。

只有封装的对象存在并且是文件夹时,这个方法才有效。

 

递归:就是函数自身调用自身。

 

什么时候用递归呢?

当一个功能被重复使用,而每一次使用该功能时的参数不确定,都由上次的功能元素结果来确定。

简单说:功能内部又用到该功能,但是传递的参数值不确定。(每次功能参与运算的未知内容不确定)。

 

递归的注意事项:

1:一定要定义递归的条件。

2:递归的次数不要过多。容易出现 StackOverflowError 栈内存溢出错误

 

其实递归就是在栈内存中不断的加载同一个函数。

 

 

Properties:一个可以将键值进行持久化存储的对象。

特点:

1,可以持久化存储数据。

2,键值都是字符串。

3,一般用于配置文件。

 

|-- load():将流中的数据加载进集合。

原理:

     其实就是将读取流和指定文件相关联。并读取一行数据,因为数据是规则的key=value所以获取一行后。通过 = 对该行数据进行切割。左边就是键,右边就是值,将键值 存储到properties集合中。

|-- store():写入各个项后,刷新输出流。

|-- list():将集合的键值数据列出到指定的目的地。

------------------------------------------------------------------------------

//Properties的基本功能:

    public static void method()

    {

        Properties prop  = new Properties();

        //添加元素:

        prop.setProperty("02","zhangsan");

        //通过键获取值:

        //System.out.println(prop.getProperty("01"));

        //获取所有的键值对:

        Set<String> keySet = prop.stringPropertyNames();

        for(String key : keySet)

        {

            System.out.println(key+":"+prop.getProperty(key));

        }

    }

------------------------------------------------------------------------------

 

PrintStream打印流

 

1:提供了更多的功能,比如打印方法。可以直接打印任意类型的数据。

2:它有一个自动刷新机制,创建该对象,指定参数,对于指定方法可以自动刷新。

3:它使用的本机默认的字符编码.

4:该流的print方法不抛出IOException。

 

该对象的构造函数。

PrintStream(File file)

          创建具有指定文件且不带自动行刷新的新打印流。

PrintStream(File file, String csn)

          创建具有指定文件名称和字符集且不带自动行刷新的新打印流。

PrintStream(OutputStream out)

          创建新的打印流。

PrintStream(OutputStream out, boolean autoFlush)

          创建新的打印流。

PrintStream(OutputStream out, boolean autoFlush, String encoding)

          创建新的打印流。

PrintStream(String fileName)

          创建具有指定文件名称且不带自动行刷新的新打印流。

PrintStream(String fileName, String csn)

 

PrintStream可以操作目的:

1:File对象。

2:字符串路径。

3:字节输出流。

 

前两个都JDK1.5版本才出现。

而且在操作文本文件时,可指定字符编码了。

 

当目的是一个字节输出流时,如果使用的println方法。可以在printStream对象上加入一个true参数。这样对于println方法可以进行自动的刷新。而不是等待缓冲区满了再刷新。

 

最终print方法都将具体的数据转成字符串。而且都对IO异常进行了内部处理。

 

既然操作的数据都转成了字符串。那么使用PrintWriter更好一些。

因为PrintWrite是字符流的子类,可以直接操作字符数据,同时也可以指定具体的编码。

 

对于PrintWriter具备了PrintStream的特点同时,还有自身特点:

该对象的目的地有四个。

1:File对象。

2:字符串路径。

3:字节输出流。

4:字符输出流。

 

直接操作文件的第二参数的编码表。

直接操作输出流的,第二参数是自动刷新。

 

开发时尽量使用PrintWriter。

 

/*

读取键盘录入将数据转成大写显示在控制台.

*/

//源:

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

 

//目的:又想把数据写到文件中。还想自动刷新。

PrintWriter out = new PrintWriter(new FileWriter("out.txt"),true);

       

        String line = null;

        while((line=bufr.readLine())!=null)

        {

            if("over".equals(line))

                break;

            out.println(line.toUpperCase());

            //out.flush();

        }

        /*

    注意:

        System.in,System.out这两个标准的输入输出流,在jvm启动时已经存在了。

        随时可以使用。当jvm结束了。这两个流就结束了。

        但是,当使用了显示的close方法关闭时,这两个流在提前结束了。

        */

        out.close();

        bufr.close();

    }

}

 

SequenceInputStream:序列流,作用就是将多个读取流合并成一个读取流。

表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

 

这样做,可以更方便的操作多个读取流。其实这个序列流内部会有一个有序的集合容器。用于存储多个读取流对象。

 

该对象的构造函数参数是枚举,想要获取枚举,需要有Vector集合。

 

既然ArrayList中没有枚举。只有自己去创建枚举对象。

但是方法怎么实现呢?因为枚举操作的是具体集合中的元素。所以无法具体实现。

但是枚举和迭代器是功能一样的。所以,可以用迭代替代枚举。

Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()

        {

            public boolean hasMoreElements()

            {

                return it.hasNext();

            }

            public FileInputStream nextElement()

            {

                return it.next();

            }

        };

这样定义很麻烦。应该想到集合框架中工具类是否有提供相应的转换方法。

Collections.enumeration(Collection c);该方法的原理往上看。

 

RandomAccessFile:

特点:

1:该对象即可读取,又可写入。

2:该对象中的定义了一个大型的byte数组,通过定义指针来操作这个数组 。

3:可以通过该对象的getFilePointer()获取指针的位置,通过seek()方法设置指针的位置。

4:该对象能操作的源和目的必须是文件。

5:其实该对象内部封装了字节读取流和字节写入流。

 

注意:实现随机访问,最好是数据有规律。

 

管道流:

管道读取流和管道写入流可以像管道一样对接上。管道读取流就可以读取管道写入流写入的数据。

 

注意:需要加入多线程技术,因为单线程,先执行read,会发生死锁,因为read方法,是阻塞式的。没有数据的read方法会让线程等待。

 

public static void main(String[] args) throws IOException

    {

        PipedInputStream pipin = new PipedInputStream();

        PipedOutputStream pipout = new PipedOutputStream();

 

        pipin.connect(pipout);

 

        new Thread(new Input(pipin)).start();

        new Thread(new Output(pipout)).start();

    }

 

对象的序列化:

目的:将一个具体的对象进行持久化。写入到硬盘上。

注意:静态数据不能被序列化,因为静态数据不在堆内存中,是存储在静态方法区中。

如何将非静态的数据不被序列化?

transient 关键字修饰此变量即可。

 

Serializable:用于启动对象的序列化功能。

 

 

IO流体系:

字符流:
Reader

|--BufferedReader
       |--LineNumberReader
|--CharArrayReader
|--StringReader
|--InputStreamReaer
       |--FileReader


Writer
 |--BufferedWriter
 |--CharArrayWriter
 |--StringWriter
 |--OutputStreamWriter
      |--FileWriter
 |--PrintWriter

 

字节流:
InputStream
 |--FileInputStream:
 |--FilterInputStream
        |--BufferedInputStream
        |--DataInputStream
 |--ByteArrayInputStream
 |--ObjectInputStream
 |--SequenceInputStream
 |--PipedInputStream


OutputStream
 |--FileOutputStream
 |--FilterOutputStream
        |--BufferedOutputStream
        |--DataOutputStream
 |--ByteArrayOutputStream
 |--ObjectOutputStream
 |--PipedOutputStream
 |--PrintStream

 

 

 

---------------------- android培训、java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima
原创粉丝点击