zoukankan      html  css  js  c++  java
  • 十、java_IO

    目录:

    一、java流式输入/输出原理

    二、java流类的分类

    三、输入/输出流类

    四、常见的节点流和处理流

    五、文件流

    六、缓冲流

    七、数据流

    八、转换流

    九、Print流

    十、Ubject流

    一、java流式输入/输出原理

    java中,对于数据的输入/输出操作以”流”(Stream)方式进行;JDK提供了各种各样的”流”类,用以获取不同类型的数据;程序中通过标准的方法输入或输出数据

    二、java流类的分类

    • 按数据流的方向不同可以分为输入流和输出流
    • 按处理数据单位不同可以分为字节流和字符流
    • 按照功能不同可以分为节点流和处理流

    jdk所提供的所有流类型位于包java.io内,分别继承自以下四种抽象流类型

      字节流 字符流
    输入流 InputStream Reader
    输出流 OutputStrean Writer

    节点流:可以从一个特定的数据源(节点)读写数据(如:文件、内存)

    处理流:是链接已存在的流(节点流或处理流)纸上,通过对数据的处理为程序提供更为强大的读写功能

    三、输入/输出流类

    1.InputStream

    继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit);下图中神色为节点流,浅色为处理流

    image

    InputSream的基本方法:

    //读取一个字节并以整数的形式返回(0-255),如果返回-1则已经到输入流的末尾
    int read() throws IOException    
    
    //读取一系列字节并存储到一个数组buffer,返回实际读取的字节数。如果读取前已经到输入流的末尾返回-1
    int read(byte[] buffer) throws IOException    
    
    //读取length个字节,并存储到一个字节数组buffer,从length位置开始,返回实际读取的字节数,如果读取前已经到输入流的末尾返回-1
    int read(byte[] buffer, int offset, int length) throws IOException    
    
    //关闭流释放内存资源
    void close() throws IOException    
    
    //跳过n个字节不读,返回实际跳过的字节数
    long skip(long n) throws IOException

    2.OutputStream

    继承自OutPutStream的流是用于程序输出数据,且数据的单位为字节(8bit);下图中神色为节点流,浅色为处理流

    image

    OutputStream的基本方法:

    //向输出流中写入一个字节数据,该字节数据为参数b的低8位
    void write(int b) throws IOException
    //将一个字节类型的数组中的数据写入输出流
    void write(byte[] b) throws IOException
    
    //将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
    void write(byte[] b, int off, int len) throws IOException
    
    //关闭流释放内存资源
    void close() throws IOException
    
    //将输出流中还从的数据全部写入到目的地
    void flush() throws IOException

    3.Reader

    继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit);下图中神色为节点流,浅色为处理流

    image

    Reader的基本方法:

    //读取一个字符并以整数的形式返回(0-255),如果返回-1则已经到输入流的末尾
    int read() throws IOException    
    
    //读取一系列字符并存储到一个数组buffer,返回实际读取的字符数。如果读取前已经到输入流的末尾返回-1
    int read(char[] buffer) throws IOException    
    
    //读取length个字符,并存储到一个字符数组buffer,从length位置开始,返回实际读取的字符数,如果读取前已经到输入流的末尾返回-1
    int read(char[] buffer, int offset, int length) throws IOException    
    
    //关闭流释放内存资源
    void close() throws IOException    
    
    //跳过n个字符不读,返回实际跳过的字符数
    long skip(long n) throws IOException

    4.Writer

    继承自writer的流都是用于程序中输出数据,且数据的单位为字符(16bit);下图中神色为节点流,浅色为处理流

    image

    Writer常用方法

    //向输出流中写入一个字符数据,该字符数据为参数b的低16位
    void write(int b) throws IOException
    
    //将一个字符类型的数组中的数据写入输出流
    void write(char[] b) throws IOException
    
    //将一个字符型的数组中的从指定位置(off)开始的len个字符写入到输出流
    void write(char[] b, int off, int len) throws IOException
    
    //将一个字符串中的字符写入到输出流
    void wrete(String string) throws IOException
    
    //将一个字符串从offset开始的length个字符写入到输出流
    void write(String string, int offset, int length) throws IOException
    
    //关闭流释放内存资源
    void close() throws IOException
    
    //将输出流中还从的数据全部写入到目的地
    void flush() throws IOException

       

    四、常见的节点流和处理流 

    1.节点流类型:

    image_thumb[1]

    2.处理流类型:

    image

    五、文件流

    FileInputStream和FileOutputStream分别继承自InputStream和OutputStream用于向文件中输入和输出字节

    FileInputStream和FileOutputStream常用构造方法:

    FileInputStream(String name) throws FileNotFoundException
    FileInputStream(File file) throws FileNotFoundException
    FileOutputStream(String name) throws FileNotFoundException
    FileOutputStream(File file) throws FileNotFoundException
    FileOutputStream(File file,boolean append) throws FileNotFoundException

    FileInputStream和FileOutputStream类支持其父类InputStream和OutputStream所提供的数据读写方法。

    注意:

    • 在实例化FileInputStream和FileOutputStraeam流时要用try-catch语句来处理其可能抛出的FileNotFoundException
    • 在读写数据时也要用try-catch语句来处理可能抛出IOException
    • FileNotFoundException是IOException的子类

    FileInputStream:

    public class Test{    
        public static void main(String[] args) {
            
            int b = 0 ;
            FileInputStream in = null;
            //打开文件
            try {
                in = new FileInputStream("F:\test.txt");//windows下路径分隔符是两个反斜杠,也可以直接使用正斜杠
            } catch (FileNotFoundException e) {
                System.out.println("找不到指定文件");
                System.exit(-1);
            }
            //读取文件
            try {
                long num = 0;
                while((b = in.read()) != -1) {
                    System.out.print((char)b);
                    num++;
                }
                in.close();
                System.out.println();
                System.out.print("共读取了 "+ num +" 个字节");
            } catch (IOException e1) {
                System.out.println("文件读取错误");
                System.exit(-1);
            }
            
        }
    }

    FileOutputStream:

    public class Test{    
        public static void main(String[] args) {
            
            int b = 0 ;
            FileInputStream in = null;
            FileOutputStream out = null;
            //打开文件
            try {
                in = new FileInputStream("F:\test.txt");//windows下路径分隔符是两个反斜杠,也可以直接使用正斜杠
                out = new FileOutputStream("F:/test1.txt");//如果目录下没有这个文件FileOutputStream会自动生成一个
                while((b = in.read()) != -1) {
                    out.write(b);//一个个字节写进去
                }
                in.close();//管道用完记得关闭
                out.close();
            } catch (FileNotFoundException e) {
                System.out.println("找不到指定文件");
                System.exit(-1);
            } catch (IOException e1) {
                System.out.println("文件复制错误");
                System.exit(-1);
            }
            System.out.print("复制成功");    
        }
    }

    FileReader:

    public class Test{    
        public static void main(String[] args) {
            
            FileReader fr = null; 
            int c = 0;
            try {
                fr = new FileReader("f:/test.txt");
                int in = 0;
                while ((c = fr.read()) != -1) {
                    System.out.print((char)c);
                }
            } catch (FileNotFoundException e) {
                System.out.print("找不到指定文件");
            } catch (IOException e1) {
                System.out.print("文件读取错误");
            }
    
        }
    }

    FileWriter:

    public class Test{    
        public static void main(String[] args) {
            
            FileReader fr = null;
            FileWriter wr = null;
            int c = 0;
            try {
                fr = new FileReader("f:/test.txt");
                wr = new FileWriter("f:/test1.txt");
                int in = 0;
                while ((c = fr.read()) != -1) {
                    wr.write(c);
                }
                wr.close();
                fr.close();
            } catch (FileNotFoundException e) {
                System.out.print("找不到指定文件");
            } catch (IOException e1) {
                System.out.print("文件写入错误");
            }
        }
    }

    六、缓冲流

    缓冲流要”套接”在相应的节点流纸上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法

    JDK提供了四种缓冲流,其常用的构造方法为:

    BufferedReader(Reader in)
    BufferedReader(Reader in,int sz)//sz为自定义缓冲区的大小
    BufferedWriter(Writer out)
    BufferedWriter(Writer out,int sz)
    BufferedInputStream(InputStream in)
    BufferedInputStream(InputStream in, int sz)
    BufferedOutputStream(OutputStream out)
    BufferedOutputStream(OutputStream out, int sz)
    • 缓冲流输入支持其父类的mark和reset方法
    • BufferedReader提供了readLine方法用于读取一行字符串(以 或 分割)
    • BufferedWriter提供了newLine用于写入一个行分隔符
    • 对于输出的缓冲流,写出的数据会现在内存中缓存,使用flush方法将会使内存中的数据立刻写出

    BufferStream1:

    public class Test{    
        public static void main(String[] args) {
            
            try {
                FileInputStream fis = new FileInputStream("f:/test.txt");
                BufferedInputStream bis = new BufferedInputStream(fis);//相当于管道套管道,为了使用缓冲区的功能
                int c = 0;
                System.out.println((char)bis.read());
                System.out.println((char)bis.read());
                
                bis.mark(100);//从100个开始往外读
                for(int i=0; i<10 && (c=bis.read()) != -1; i++) {
                    System.out.print((char)c + " ");
                }
                System.out.println();
                bis.reset();//回到100的那个点上
                for(int i=0; i<=10 && (c=bis.read()) != -1; i++) {
                    System.out.print((char)c + " ");
                }
                bis.close();
            } catch(IOException e) {
                e.printStackTrace();
            }    
        }
    }

    BufferStream2:

    public class Test{    
        public static void main(String[] args) {
            
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter("f:/test.txt"));//管道套接
                BufferedReader br = new BufferedReader(new FileReader("f:/test.txt"));
                //写入
                String s = null;
                for(int i=1; i<100; i++) {
                    s = String.valueOf(Math.random());//产生一个字符串的随机数
                    bw.write(s);//写一个字符串到缓冲区
                    bw.newLine();//写一个换行到缓冲区
                }
                bw.flush();//将缓存内存中的数据写出
                //逐行读取
                while((s=br.readLine()) != null) {
                    System.out.println(s);
                }
                
                bw.close();
                br.close();
            } catch(IOException e) { 
                e.printStackTrace();
            }    
        }
    }

        

    七、数据流

    • DataInputStream和DataOutPutStream分别继承自InputStream和OutPutStream,它属于处理流,需要分别”套接”在InputStream和OutputStream类型的节点流上
    • DataInputStream和DataOutputStream提供了可以存取与机器无关的java原始类型数据(如:int,double等)的方法
    • DataInputStream和DataOutputStream的构造方法为:
    DataInputStream(InputStream in)
    DataOutputStream(OutputStream out)

    看一个例子:

    public class Test{    
        public static void main(String[] args) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();//在内存中分配字节数组
            DataOutputStream dos = new DataOutputStream(baos);//套接
            
            try {
                dos.writeDouble(Math.random());//写一个double类型的随机数,double是8个字节
                dos.writeBoolean(true);//写一个布尔值进去,布尔值在内存中只占一个字节
                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());//读数据,只能一个字节一个字节读
                System.out.println(bais.available());//输出字节数
                
                DataInputStream dis = new DataInputStream(bais);//套接
                System.out.println(dis.readDouble());//输出数据1,注意,先写的先读
                System.out.println(dis.readBoolean());//输出数据2
                dos.close();
                dis.close();
                
            } catch(IOException e) {
                e.printStackTrace();
            }
        }
    }

    八、转换流

    • InputStreamReader和OutputStreamWriter用于字节数据到字符数据之间的转换
    • InputStreamReader需要和InputStream”套接”
    • OutputStreamWriter需要和OutputStream”套接”
    • 转换流在构造时可以指定其编码集合,例如:InputStream isr = new InputStreamReader(System.in, “ISO8859_1”)

    OutputStreamWriter:

    public class Test{    
        public static void main(String[] args) {
    
            try {            
                OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("f:/test.txt"));
                osw.write("aaa");            
                System.out.println(osw.getEncoding());    //获取osw的字符编码        
                  osw.close();
                //true表示在原文件的基础上追加,如果不加true,则会删除原文件的内容后再写入新的内容,ISO8859_1是一种字符编码,指定了要写入内容的编码格式
                  osw = new OutputStreamWriter(new FileOutputStream("f:/test.txt", true), "ISO8859_1");
                osw.write("bbb");
                System.out.println(osw.getEncoding());
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    InputStreamReader:

    /*
     * 这个程序相当于一直逐行读取键盘输入,直到输入exit为止,这是一种阻塞式的方法,程序运行起来后不输入exit程序就一直停在那,也可以理解为是同步式的
     */
    
    public class Test{    
        public static void main(String[] args) {
            InputStreamReader isr = new InputStreamReader(System.in);//System.in是接收的键盘输入
            BufferedReader br = new BufferedReader(isr);
            String s = null;
            
            try {
                s = br.readLine();
                //除非s="exit"否则就不停的读
                while(s != null) {
                    if(s.equalsIgnoreCase("exit")) {
                        break;
                    } else {
                        System.out.println(s.toUpperCase());
                        s = br.readLine();
                    }                
                }
                br.close();            
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    九、Print流

    • PrintWriter和PrintStream都属于输出流,分别针对与字符和字节
    • PrintWriter和PrintStream提供了重载的print
    • Println方法用于多种数据类型的输出
    • PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
    • PrintWriter和PrintStream有子的佛那个flush功能
    PrintWriter(Writer out)
    PrinWriter(Writer out,boolean autoFlush)
    PrintWriter(OutputStream out)
    PrintWriter(PutputStream out, boolean autoFlush)
    PrintStream(OutputStream out)
    PrintStream(OutputStream out, boolean autoFlush)

    例子1:

    public class Test{    
        public static void main(String[] args) {
            PrintStream ps = null;
            
            try {
                FileOutputStream fos = new FileOutputStream("f:/test.txt");
                ps = new PrintStream(fos);//套接
            } catch(IOException e) {
                e.printStackTrace();
            }
            
            if(ps != null) {
                System.setOut(ps);//更改默认输出位置为ps,System.out默认指向的是控制台
            }
            
            int ln = 0;
            for(char c=0; c<=60000; c++) {
                System.out.print(c+" ");
                if(ln++ >= 100) {
                    System.out.println();
                    ln = 0;
                }
            }
        }
    }

    例子2:

    public class Test{    
        public static void main(String[] args) {
            String filename = args[0];//外部传参
            if(filename != null) {
                list(filename,System.out);
            }
        }
        public static void list(String f,PrintStream fs){
            try {
                BufferedReader br = new BufferedReader(new FileReader(f));
                String s = null;
                //按行读取
                while((s=br.readLine()) != null) {
                    fs.println(s);
                }
                br.close();
            } catch(IOException e) {
                fs.println("无法读取文件");
            }
        }
    }

    例子3:

    public class Test{    
        public static void main(String[] args) {
            String s = null;
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//System.in是键盘输入
            
            try {
                FileWriter fw = new FileWriter("f:/test.txt",true);//true追加在原文件后面
                PrintWriter log = new PrintWriter(fw);
                
                while((s=br.readLine()) != null){
                    if(s.equalsIgnoreCase("exit")){
                        break;//如果键盘输入exit则停止运行
                    }
                    
                    System.out.println(s.toUpperCase());//控制台输出
                    log.println("----");
                    log.println(s.toUpperCase());//写入
                    log.flush();
                }
                log.println("==="+new Date()+"===");//new Date()指的是util里的date,也就是当前时间
                log.flush();
                log.close();
            } catch(IOException e) {
                e.printStackTrace();
            }
        }
    }

    十、Ubject流

    作用:直接将Object写入或读出

    • transient关键字
    • serializable接口      标记类里的对象可以序列化
    • externalizable接口    控制类的对象是怎么写出去的,也就是说可以自己控制序列化过程

    看一个例子:

    class T implements Serializable{//如果要写入或者读对象必须要实现Serializable接口,这是一个标记接口,所以不需要重写方法
        int i = 0;
        int j = 9;
        double d = 2.3;
        int k = 0;
    }
    public class Test{    
        public static void main(String[] args) throws Exception{
            T t = new T();
            t.k = 8;
            FileOutputStream fos = new FileOutputStream("f:/test.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            
            oos.writeObject(t);//把t对象写入f:/test.txt
            oos.flush();
            oos.close();
            
            FileInputStream fis = new FileInputStream("f:/test.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            
            T tReaded = (T)ois.readObject();//读对象
            System.out.println(tReaded.i+" "+tReaded.j+" "+tReaded.d+" "+tReaded.k);
        }
    }

    上面例子中的输出结果为:0    9    2.3    8

    如果将T里的 int k = 0; 改为 transient int k = 0;

    则输出结果应该是0    9    2.3    0

    因为transient相当于把k变成了透明的,使用transient修饰的成员变量在序列化(操作对象)的时候不予考虑

  • 相关阅读:
    AX88772B 驱动移植
    USB 驱动之 usb_register 函数解析
    am335x USB 驱动框架记录
    warning: assignment from incompatible pointer type [enabled by default]
    WARNING: arch/arm/mach-omap2/built-in.o(.text+0x12cdc): Section mismatch in reference from the function mmc0_init() to the (unknown reference) .init.data:(unknown)
    Oracle11g客户端client的下载与安装
    sqlserver2008R2 评估期已过
    SQL2008 提示评估期已过的解决方法
    Windows下Oracle定时备份(全量备份)
    某客的《微信小程序》从基础到实战视频教程
  • 原文地址:https://www.cnblogs.com/JianXu/p/5768328.html
Copyright © 2011-2022 走看看