zoukankan      html  css  js  c++  java
  • IO 复习笔记

    输入流,从源到流中;输出流,从流到目的地。

    1. 操作文件:

        1).写入:FileOutputStream或者FileWriter

        2).读取:FileInputStream或者FileReader

        3).随机读写:RandomAccessFile

        4).文件属性:File

    2. 通过Java IO中的PipedOutputStream和PipedInputStream创建管道。一个PipedInputStream流应该和一个PipedOutputStream流相关联。一个线程通过PipedOutputStream写入

        的数据可以被另一个线程通过相关联的PipedInputStream读取出来。

        关联方式:

        1). PipedOutputStream fos = new PipedOutputStream();

             PipedInputStream fis = new PipedInputStream();

        2). fis.connect(fos);

        3). fos.connect(fis);

    3. 请记得,当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁。

    4. 用ByteArrayInputStream或者CharArrayReader封装字节或者字符数组从数组中读取数据。也可以把数据写到ByteArrayOutputStream或者CharArrayWriter中。

    5. System.in, System.out, System.err这3个流同样是常见的数据来源和数据流目的地。JVM启动的时候通过Java运行时初始化这3个流,所以你不需要初始化它们(尽管你可以在运行时替换掉它们)。

    6. 某些类似PushbackInputStream 流的实现允许你将数据重新推回到流中,以便重新读取。然而你只能把有限的数据推回流中,并且你不能像操作数组那样随意读取数据。流中的数据只能够顺序访问。

    7. 字节流通常以“stream”命名,比如InputStream和OutputStream。除了DataInputStream 和DataOutputStream 还能够读写int, long, float和double类型的值以外,其他流在一个操作时间内只能

        读取或者写入一个原始字节。字符流通常以“Reader”或者“Writer”命名。字符流能够读写字符(比如Latin1或者Unicode字符)。(不一定是两字节)

    8. Java IO流是既可以从中读取,也可以写入到其中的数据流。正如这个系列教程之前提到过的,流通常会与数据源、数据流向目的地相关联,比如文件、网络等等。

    9. 请注意,InputStream的read()方法返回一个字节,意味着这个返回值的范围在0到255之间(当达到流末尾时,返回-1),Reader的read()方法返回一个字符,意味着这个返回值的范围在0到65535之间

        (当达到流末尾时,同样返回-1)。这并不意味着Reade只会从数据源中一次读取2个字节,Reader会根据文本的编码,一次读取一个或者多个字节。

    10. 一个Reader可以和一个InputStream相结合。如果你有一个InputStream输入流,并且想从其中读取字符,可以把这个InputStream包装到InputStreamReader中。把InputStream传递到

          InputStreamReader的构造函数中:

          Reader reader = new InputStreamReader(inputStream);

          在构造函数中可以指定解码方式。

    11. 与Reader和InputStream类似,一个Writer可以和一个OutputStream相结合。把OutputStream包装到OutputStreamWriter中,所有写入到OutputStreamWriter的字符都将会

           传递给OutputStream。这是一个OutputStreamWriter的例子:

           Writer writer = new OutputStreamWriter(outputStream);

    12. 流与Reader和Writer在结束使用的时候,需要正确地关闭它们。通过调用close()方法可以达到这一点。如果代码出现了异常,会发生什么呢?没错,这个InputStream对象就不会被关闭。

    13. Try-with-resources

          In Java 7 you can write the code from the example above using the try-with-resource construct like this:

                 private static void printFileJava7() throws IOException {

                          try(FileInputStream input = new FileInputStream("file.txt")) {

                          int data = input.read();

                          while(data != -1){

                                  System.out.print((char) data);

                                  data = input.read();

                          }

                      }

               }

    14. 如果read()方法返回-1,意味着程序已经读到了流的末尾,此时流内已经没有多余的数据可供读取了。-1是一个int类型,不是byte或者char类型,这是不一样的。当达到流末尾时,你就可以关闭流了。

    15. InputStream包含了2个从InputStream中读取数据并将数据存储到缓冲数组中的read()方法,他们分别是:

          int read(byte[])

          int read(byte, int offset, int length)

          一次性读取一个字节数组的方式,比一次性读取一个字节的方式快的多,所以,尽可能使用这两个方法代替read()方法。

    16. write(byte)方法用于把单个字节写入到输出流中。OutputStream的write(byte)方法将一个包含了待写入数据的int变量作为参数进行写入。只有int类型的第一个字节会被写入, 其余位会被忽略。

          (译者注:写入低8位,忽略高24位)。

    17. OutputStream同样包含了将字节数据中全部或者部分数据写入到输出流中的方法,分别是write(byte[])和write(byte[], int offset, int length)。

          write(byte[])把字节数组中所有数据写入到输出流中。

          write(byte[], int offset, int length)把字节数据中从offset位置开始,length个字节的数据写入到输出流。

    18. OutputStream的flush()方法将所有写入到OutputStream的数据冲刷到相应的目标媒介中。比如,如果输出流是FileOutputStream,那么写入到其中的数据可能并没有真正写入到磁盘中。

          即使所有数据都写入到了FileOutputStream,这些数据还是有可能保留在内存的缓冲区中。通过调用flush()方法,可以把缓冲区内的数据刷新到磁盘(或者网络,以及其他任何形式的目标媒介)中。

    19. 当你创建了一个指向已存在文件的FileOutputStream,你可以选择覆盖整个文件,或者在文件末尾追加内容。通过使用不同的构造函数可以实现不同的目的

    20. RandomAccessFile允许你来回读写文件,也可以替换文件中的某些部分。FileInputStream和FileOutputStream没有这样的功能。创建一个RandomAccessFile在使用RandomAccessFile之前,

          必须初始化它。这是例子:

          RandomAccessFile file = new RandomAccessFile("c:\data\file.txt", "rw");

          请注意构造函数的第二个参数:“rw”,表明你以读写方式打开文件。请查阅Java文档获知你需要以何种方式构造RandomAccessFile。

          在RandomAccessFile中来回读写。在RandomAccessFile的某个位置读写之前,必须把文件指针指向该位置。通过seek()方法可以达到这一目标。可以通过调用getFilePointer()获得当前

          文件指针的位置。

    21. File:检测文件是否存在,文件长度,重命名或移动文件,删除文件,检测某个路径是文件还是目录,读取目录中的文件列表

    22. ByteArrayInputStream允许你从字节数组中读取字节流数据。ByteArrayOutputStream允许你以数组的形式获取写入到该输出流中的数据。

    23. BufferedInputStream能为输入流提供缓冲区,能提高很多IO的速度。你可以一次读取一大块的数据,而不需要每次从网络或者磁盘中一次读取一个字节。特别是在访问大量磁盘数据时,

          缓冲通常会让IO快上许多。你可以给BufferedInputStream的构造函数传递一个值,设置内部使用的缓冲区设置大小(译者注:默认缓冲区大小8 * 1024B),就像这样:

          InputStream input = new BufferedInputStream(new FileInputStream("c:\data\input-file.txt"), 8 * 1024);

          这个例子设置了8KB的缓冲区。最好把缓冲区大小设置成1024字节的整数倍,这样能更高效地利用内置缓冲区的磁盘。

    24. BufferedOutputStream可以为输出流提供缓冲区。可以构造一个使用默认大小缓冲区的BufferedOutputStream(译者注:默认缓冲区大小8 * 1024B),也可以手动设置缓冲区大小,代码如下:

          OutputStream output = new BufferedOutputStream(new FileOutputStream("c:\data\output-file.txt"), 8 * 1024);

          为了更好地使用内置缓冲区的磁盘,同样建议把缓冲区大小设置成1024的整数倍。需要手动flush()方法确保写入到此输出流的数据真正写入到磁盘或者网络中。

    25. DataInputStream可以使你从输入流中读取Java基本类型数据,而不必每次读取字节数据。你可以把InputStream包装到DataInputStream中,然后就可以从此输入流中读取基本类型数据。

          DataOutputStream可以往输出流中写入Java基本类型数据

    26. 如果你希望类能够序列化和反序列化,必须实现Serializable接口。

          ObjectInputStream能够让你从输入流中读取Java对象,而不需要每次读取一个字节。你可以把InputStream包装到ObjectInputStream中,然后就可以从中读取对象了,然后强制转换为对应的类型。

          ObjectOutputStream能够让你把对象写入到输出流中,而不需要每次写入一个字节。你可以把OutputStream包装到ObjectOutputStream中,然后就可以把对象写入到该输出流中了。

    27. Java内部使用UTF8编码表示字符串。输入流中一个字节可能并不等同于一个UTF8字符。如果你从输入流中以字节为单位读取UTF8编码的文本,并且尝试将读取到的字节转换成字符,

          你可能会得不到预期的结果。

    28. Writer的write(int c)方法,会将传入参数的低16位写入到Writer中,忽略高16位的数据。

    29. InputStreamReader和OutputStreamWriter,这两个类把字节流转换成字符流,中间做了数据的转换,类似适配器模式的思想。

          InputStreamReader同样拥有其他可选的构造函数,能够让你指定将底层字节流解释成何种编码的字符流。OutputStreamWriter同样拥有将输出字节流转换成指定编码的字符流的构造函数。

    30. FileReader拥有其他可选的构造函数,能够让你使用不同的方式读取文件,更多内容请查看官方文档。FileReader会假设你想使用你所使用的JVM的版本的默认编码处理字节流,但是这通常不是你想要的,

          你可以手动设置编码方案。如果你想明确指定一种编码方案,利用InputStreamReader配合FileInputStream来替代FileReader(译者注:FileReader没有可以指定编码的构造函数)。InputStreamReader可

          以让你设置编码处理从底层文件中读取的字节。处理文件都会碰到的一个问题是,当前写入的数据是覆盖原文件内容还是追加到文件末尾。当你创建一个FileWriter之后,你可以通过使用不同构造函数实现

          你的不同目的。

    31. BufferedReader、BufferedWriter

    32. PushbackInputStream,SequenceInputStream,PrintStream,PushbackReader,LineNumberReader,StreamTokenizer,PrintWriter,StringReader,StringWriter

          LineNumberReader是记录了已读取数据行号的BufferedReader。默认情况下,行号从0开始,当LineNumberReader读取到行终止符时,行号会递增。你可以通过getLineNumber()方法获取当前行号,

          通过setLineNumber()方法设置当前行数。setLineNumber()仅仅改变LineNumberReader内的记录行号的变量值,不会改变当前流的读取位置。流的读取依然是顺序进行,意味着你不能通过

          setLineNumber()实现流的跳跃读取

          StreamTokenizer可以识别标示符,数字,引用的字符串,和多种注释类型。你也可以指定何种字符解释成空格、注释的开始以及结束等。在StreamTokenizer开始解析之前,所有的功能都可以进行配置。

          StringReader能够将原始字符串转换成Reader:Reader reader = new StringReader("input string...");

          StringWriter能够以字符串的形式从Writer中获取写入到其中数据:

          StringWriter writer = new StringWriter(); 

          String data = writer.toString();

          StringBuffer dataBuffer = writer.getBuffer(); 

     


  • 相关阅读:
    Linux 打印可变参数日志
    am335x system upgrade kernel f-ram fm25l16b(十六)
    spi signal analyze using logic analyzer
    learning armbian steps(3) ----- armbian 文件系统定制思路
    learning armbian steps(2) ----- armbian 镜像编译
    learning armbian steps(1) ----- armbian 入门知识基础学习
    create rootfs.img using loop device
    learning docker steps(8) ----- docker network 初次体验
    learning docker steps(7) ----- docker registry 搭建
    learning docker steps(6) ----- docker 镜像加速
  • 原文地址:https://www.cnblogs.com/Jtianlin/p/4908369.html
Copyright © 2011-2022 走看看