• JAVAI/O流


    一. I/O流概述

       输入输出处理是程序设计中非常重要的一部分,从键盘中读数据或从文件中读写数据等等。

         java把这些不同类型的输入、输出源抽象为流(stream),用统一接口来表示,从而使程序简单明了。

    I/O中的Exception

      进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。  

      如:FileNotFoundException, EOFException, IOException

    java.io包中有关文件处理包括:

                类:File、FileInputStream、FileOutputStream、RamdomAccessFile和FileDescription

                    接口:FilenameFilter

    1. 字节流:

      从InputStream和OutputStream派生出来的一系列类,以字节(byte)为基本处理单位

    2. 字符流:

      从Reader和Writer派生出来的一系列类,以16位的Unicode码表示的字符为基本处理单位

    3. 对象流:

      ObjectInputStream、ObjectOutputStream

    4. 其他

         文件处理:

        文件处理:

          File、RandomAccessFIle

        接口:

          DataInput、DataOutput、ObjectInput、ObjectOutput

    二. 文件描述

      类File:并不代表磁盘上的文件,可以理解为文件的路径,但是比String形式的路径更为安全。

      1)文件或目录的生成

        public File(String path); // 如果path是路径,则该File对象表示的是目录;如果path是文件名,则该表示的是文件

        public File(String path, String name); // path是路径名,name是文件名

        public File(File dir, String name); // dir是路径名,name是文件名

      2)文件名的处理

        String getName(); // 得到一个文件的名称(不包括路径)

        String getPath(); // 得到一个文件的路径名

        String getAbsolutePath(); // 得到一个文件的绝对路径名

        String getParent(); // 得到一个文件的上一级目录名

        String renameTo(File newName); // 将当前文件名更名为给定文件的完整路径

      3)文件属性测试

        boolean exists(); // 测试当前FIle对象所指示的文件是否存在

        boolean canWrite(); // 测试当前文件是否可写

        boolean canRead(); // 测试当前文件是否可读

        boolean isFile(); // 测试当前文件是否是文件

        boolean isDirectory; //  测试当前文件是否是目录

      4)普通文件信息和工具

        long lastModified(); // 得到文件最近一次修改的时间

        long length(); // 得到文件的长度,以字节为单位

        boolean delete(); // 删除当前文件

      5)目录操作

        boolean mkdir(); // 根据当前对象生成以一个由该对象指定的路径

        String list(); // 列出当前目录下的文件。

               // File假如是一个Directory,可以通过list()方法得到这个目录下所有的文件和目录的名称数组。

              // 一种是没有参数,一种是实现FilenameFilter接口的参数。

       

         FilenameFilter接口,能够过滤得到指定类型的文件或者目录,其中必须重写accept(File file,String path)方法

    eg: 列出C:\MyProjects下后缀为.java的文件

     1 import java.io.*;
    2
    3 public class FileFilterTest {
    4 public static void main(String args[]) {
    5 File dir = new File("C://MyProjects"); // 用File对象表示一个目录
    6 Filter filter = new Filter("java"); // 生成一个名为java的过滤器
    7 System.out.println("list java files in directory" + dir);
    8
    9 String files[] = dir.list(filter); // 列出目录dir下,文件名后缀名为java的所有文件
    10
    11 for (int i = 0; i < files.length; i++) {
    12 File f = new File(dir, files[i]); // 为目录dir下的文件或目录创建一个File对象
    13 if (f.isFile())
    14 System.out.println("file " + f);
    15 else
    16 System.out.println("sub dirctory " + f);
    17 }
    18 }
    19 }
    20
    21 class Filter implements FilenameFilter { // 必须重写accept(File file,String path)方法
    22 String extent;
    23
    24 Filter(String extent) {
    25 this.extent = extent;
    26 }
    27
    28 public boolean accept(File dir, String name) {
    29 return name.endsWith("." + extent); //返回文件的后缀名
    30 }
    31 }

     

    二. I/O流详述

    1. 字节流

    InputStream类

      a) 从流中个读取数据

        int read(); // 读取一个字节,返回实际所读字节

        int read(byte b[]); // 读取字节数为b的长度,并存放在字节数组b中,返回值为实际读取的字节的数量

        int read(byte b[], int off, int len); // 读取len个字节,放置在以下标off开始的字节数组b中,返回值为实际读取的字节的数量

        int available(); // 返回值为流中尚未读取的字节的数量

        long skip(long n); // 读指针跳过n个字节不读,返回值为实际跳过的字节数量

      b) 关闭流:

        close(); // 流操作完毕后必须关闭

      c) 使用输入流中的标记:

        void mark(int readlimit); // 记录当前读指针所在位置,readlimit表示读指针读出readlimit个字节后标记的指针位置才失效

        void reset(); // 把读指针重新指向用mark方法所记录的位置

        boolean markSupported(); // 当前的流是否支持读指针的记录功能

    OutputStream类

      a) 输出数据:

        void write(int b); // 往流中写一个字节b

        void write(byte b[]); // 往流中写一个字节数组b

        void write(byte b[], int off, int len); // 把字节数组b中下标off开始,长度为len的字节写入流中

        flush(); // 刷空输出流,并输出所有被缓存的字节,由于某些流支持缓存的功能,该方法将把缓存中所有内容强制输出到流中

      b) 关闭流:

        close(); // 流操作完毕后必须关闭

    过滤流(包装流)

      过滤流在读写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流

      防止多个线程同时对一个I/O流进行操作带来的意想不到的结果。

      类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类

       a) 使用过滤流的步骤:

        连接到某个输入输出流上,通过在构造方法的参数中指定所要连接的输入输出流上来实现

        FilterInputStream(InputStream in);

        FilterOutputStream(OutputStream out);

       b) 几种常见的过滤流

        BufferedInputStream和BufferedOutputStream 缓冲流,用于提高输入输出处理的效率

        DataInputStream和DataOutputStream 不仅能读写数据流,而且读写各种java语言的基本类型

        LineNumberInputStream 除了对输入处理的支持外,可以记录当前的行号

        PushbackInputStream 提供了一个方法可以把刚读的字节退回到输入流中,以便重新再读一遍

        PrintStream 打印流的作用是吧java语言的内构类型以其字符表示形式动到相应的输出流

    2. 字符流

    字符流的处理

      java提供16位Unicode码表示的字符流的类,即以Reader和Writer为基类派生出的一系列类

      Reader和Writer:这两个类是抽象类,只是提供了一系列用于字符流处理的接口,不能生成实例。

    Reader类:是处理所有字符流输入类的父类

      a) 读取字符

        public int read() throws IOException; // 读取一个字符,返回值为读取的字符

        public int read(char cbuf[]) throws IOException; // 读取一系列字符到cbuf数组,返回值为实际读取的字符数量

        public abstract int read(char cbuf[], int off, int len) throws IOException; // 读取len个字符,存入off开始的cbuf中,返回实际读取的    // 的字数,必须由子类实现

       b) 标记流

        public boolean markSupported(); // 判断当前流是否支持做标记

        public void mark(int readAheadLimit) throws IOException; // 给当前流作标记,最多支持readAheadLimit个字符的回溯

        public void reset() throws IOException; // 将当前流重置到做标记处

      c) 关闭流

        public abstract void close() throws IOExeption;

    Writer类:是处理所有字符流输出类的父类

      a) 向输出流写入字符

        public void write(int c) throws IOException; // 将整型值c的低16位写入输出流

        public void write(char cbuf[]) throws IOException; // 将cbuf数组写入输出流

        public abstract void write(char cbuf[], int off, int len); // 将字符数组cbuf中的从索引off开始的len个字符写入输出流

        public void write(String str) throws IOException; // 将字符串str中的字符写入输出流

        public void write(String str, int off, int len) throws IOException; // 将字符串str中从索引off开始处的len个字符写入输出流

        flush() 刷空输出流,并输出所有被缓冲的字节

      b) 关闭流

        public abstract void close() throws IOException;

    java.io包中用于处理字符流的最基本的类:InputStreamReader OutputStreamWriter,此外还有FileReader和FileWriter

      a) 生成流对象

          public InputStreamReader(InputStream in); // in是字节流,即将字节流转换成字符流来处理

          public InputStreamReader(InputStream in, String enc) throws UnsupportedEncodingExceptio; // enc是编码方式:ISO8859-1,UTF-8,UTF-16

          public OutputStreamWriter(OutputStream out); // out是字节流

          public OutputStreamWriter(OutputStream out, String enc) throws UnsupportedEncodingException; // enc是编码方式

      b) 读写字符

        基本与Reader和Writer一致

      c) 获取当前编码方式

        public String getEncoding();

      d) 关闭流

        public void close() throws IOException;

    BufferedReader和BufferedWriter

      a) 生成流对象

        public BufferedReader(Reader in); 

        public BufferedReader(Reader in, int sz); // sz为缓冲区的大小

        public BufferedWriter(Writer out); 

        public BufferedWriter(Writer out, int sz); 

      b) 读写字符

        增加对整行字符的处理

        public String readline() throws IOException; // 读一行字符

        public void newLine() throws IOException; // 写一行字符

       

     1 // 从键盘读入数字,并输出
    2 import java.io.*;
    3
    4 public class NumberInput {
    5 public static void main(String args[]) {
    6 try {
    7 InputStreamReader ir;
    8 BufferedReader in;
    9 ir = new InputStreamReader(System.in);
    10 // 从键盘接受一个字符串的输入,并创建了一个字符输入流的对象
    11 in = new BufferedReader(ir); // 用字符输入流ir创建一个BufferedReader对象
    12 String s = in.readLine(); // 从输入流in中读入一行
    13 System.out.println("Input value is: " + s);
    14 int i = Integer.parseInt(s); // 转换成int
    15 i *= 2;
    16 System.out.println("Input value changed after doubled: " + i);
    17 }
    18 catch (IOException e) {
    19 System.out.println(e);
    20 }
    21 }
    22 }

    3. 对象流

      串行

        对象通过描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)

        a) 串行化方法:

          java.io包中,接口Serializable用来作为对象串行化的工具,只有实现了Serializable的对象才可以被串行化

          串行化步骤:

     1         1. 定义一个可串行化的对象
     2 
     3           public class Student implements Serializable {...}
     4 
     5         2. 通过ObjectInputStream和ObjectOutputStream这两个对象流存取可串行化对象
     6 
     7           Student stu = new Student();
     8 
     9           FileOutputStream fo = new FileOutputStream("data.ser");
    10 
    11           ObjectOutputStream so = new ObjectOutputStream(fo);
    12 
    13           try {
    14 
    15             so.writeObject(stu);
    16 
    17             so.close();
    18 
    19           } catch (IOException e) {
    20 
    21             System.out.println(e);
    22 
    23           }
    24 
    25           FileInputStream fi = new FileInputStream("data.ser");
    26 
    27           ObjectInputStream si = new ObjectInputStream(fi);
    28 
    29           try {
    30 
    31             stu = (student)si.readObject();
    32 
    33             si.close();
    34 
    35           } catch (IOException e) {
    36 
    37             System.out.println(e);
    38 
    39           }        

    注意事项:

    1. 只能保存非静态成员变量,不能保存任何成员方法和静态成员变量,保存的只是变量的值,对于变量的任何修饰符都无法保存

    2. transient关键字,对于某些瞬时对象(Thread对象,FileInputStream对象),无法保存,必须用transient关键字表明

    3. 定制串行化,缺省机制为按名称升序,想定制就要重写writeObject()和readObject()

    4. 其他常用的流

    管道流

      用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入

      在使用管道前,管道输出流和管道输入流必须进行连接。

      a) 构造方法连接

        PipedInputStream(PipedOutputstream src);

        PipedOutputStream(PipedInputStream snk);

      b) connect方法进行连接

        类PipedInputStream中定义为:

        void connect(PipedOutputSream src);

        类PipedOutputStream中定义为:

          void connect(PipedInputSream snk);

    小结: 

    字节流:

      抽象类 InputStream OutputStream
      跟数据源直接接触的类: FileInputStream FileOutputStream
      装饰类: BufferedInputStream: 提供了缓冲功能 BufferedOutputStream: 提供缓冲功能

      重要方法:
        read();
        read(byte[] b);
        read(byte[] b, int off, int len);

        write(int b);
        write(byte[] b);
        write(byte[] b, int off, int len);

    字符流:

      抽象类 Reader Writer
      跟数据源直接接触的类 FileReader FileWriter
      装饰类 BufferedReader: 缓冲,readLine() BufferedWriter: 缓冲

      重要方法:
        read(char[] cbuf);
        read(char[] cbuf, int off, int len);
        read(CharBuffer target);

        write(char[] cbuf);
        write(char[] cbuf, int off, int len);
        write(int c);
        write(String str);
        write(String str, int off, int len);

    对象流
      需要被序列化的对象必须实现Serializable接口
      调用ObjectOutputStream的writeObject()方法,通过装饰FileOutputstream
      调用ObjectInputStream的readObject()方法,通过装饰FileInputStream

  • 相关阅读:
    零点定理、介值定理
    古今数学史
    古今数学史
    StreamDM:基于Spark Streaming、支持在线学习的流式分析算法引擎
    StreamDM:基于Spark Streaming、支持在线学习的流式分析算法引擎
    随机化算法(二)
    随机化算法(二)
    机器学习算法时间复杂度的考虑
    机器学习算法时间复杂度的考虑
    matlab 工具函数、matlab toolbox(工具箱)
  • 原文地址:https://www.cnblogs.com/forstudy/p/2436643.html
Copyright © 2020-2023  润新知