zoukankan      html  css  js  c++  java
  • Java IO之简单输入输出

    Java中的IO分为两个部分,以InputStream和Reader为基类的输入类,以OutputStream和Writer为基类的输出类。

    当中InputStream和OutputStream以字节为单位进行IO。而Reader和Writer以字符为单位。

    除了输入输出,另一系列类库称为Filter,或成为装饰器。

    对于输入可用FilterInputStream和FilterReader的派生类,输出可用FilterOutputStream和FilterWriter的派生类。当中FilterInputStream和FilterOutputStream以字节为单位,FilterReader和FilterWriter以字符为单位。

    另一个独立与InputStream和OutputStream的—RandomAccessFile。用于对文件的读写,有点相似与C语言中的fopen()

    所以能够总结,全部以Stream结尾的都是以字节为单位,也成为流;以Reader或Writer结尾的都以字符为单位。Reader和Writer在java1.1中才出现,假设须要进行转换,能够使用InputStreamReader和OutputStreamWriter。

    过滤器(Filter)

    Filter是对输入或输出进行一定的控制,如缓存、读取或写入基本数据类型等。用于更改流的一些行为。

    FilterInputStream的派生类:

    这里写图片描写叙述

    FilterOutputStream的派生类:

    这里写图片描写叙述

    Reader和Writer中所用的Filter与InputStream和OutputStream中的Filter对照:

    这里写图片描写叙述

    对于Filter的详细使用将在详细综合样例中讲到。

    输入

    输入分为输入字节和输入字符。分别使用基类是InputStream和Reader,假设须要把InputStrema转化为Reader,能够使用InputStreamReader。下面是一些InputStream经常使用的派生类与Writer与之相应的派生类。

    InputStream派生类:

    这里写图片描写叙述

    Reader与之相应的派生类:

    这里写图片描写叙述

    将InputStream转成Reader演示样例:

    // 创建一个InputStream类型的对象
    InputStream in = new FileInputStream("data.txt");
    // InputStreamReader继承自Reader。其构造方法接受一个InputStream对象
    Reader reader = new InputStreamReader(in);

    输出

    输出分为输出字节和输出字符,分别使用基类是OutputStream和Writer,假设须要把OutputStrema转化为Writer,能够使用OutputStreamWriter。

    下面是一些OutputStream经常使用的派生类与Writer与之相应的派生类。

    OutputStream派生类:

    这里写图片描写叙述

    Writer与之相应的派生类:

    这里写图片描写叙述

    将OutputStream转成Writer演示样例:

    // 创建一个OutputStream类型的对象
    OutputStream out=new FileOutputStream("data.txt");
    // OutputStreamWriter继承自Writer,其构造方法接受一个OutputStream对象
    Writer writer=new OutputStreamWriter(out);

    综合演示样例

    1、打开一个文件。并把当中的内容逐行输出的屏幕上。为了提高效率。这里将使用第一种过滤器BufferedReader,能够对输入进行缓冲。

    public class Read {
        public static void main(String[]args) throws Exception{
            String file="data.txt";
            read(file);
        }
    
        public static void read(String file) throws Exception{
            BufferedReader in=new BufferedReader(new FileReader(file));
            String s;
            while((s=in.readLine())!=null)
                System.out.println(s);
            in.close();
        }
    }

    2、从文件中按字节读取内容,须要用到DataInputStream过滤器,因为这里要对字节进行操作,所以要使用InputStream而不是Reader。当中对是否是用BufferedStream进行效率比較。

    import java.io.*;
    
    public class ReadByte {
        public static void main(String[] args) throws Exception {
            String file = "data.txt";
            long start;
            start = System.currentTimeMillis();// 记录执行開始时间
            readWithBufferedInputStream(file);
            System.out.println("readWithBufferedInputStream use time:"
                    + (System.currentTimeMillis() - start));// 执行结束时间-開始时间就是执行时间
            start = System.currentTimeMillis();
            readWithoutBufferedInputStream(file);
            System.out.println("readWithoutBufferedInputStream use time:"
                    + (System.currentTimeMillis() - start));
        }
    
        public static void readWithBufferedInputStream(String file)
                throws Exception {
            // 用BufferedInputStream进行读取文件
            DataInputStream in = new DataInputStream(new BufferedInputStream(
                    new FileInputStream(file)));
            while (in.available() != 0)
                // DataInputStream剩余的字符数不为零则表示还没输出结束
                in.readByte();
            in.close();
        }
    
        public static void readWithoutBufferedInputStream(String file)
                throws Exception {
            // 不用BufferedInputStream读取文件
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            while (in.available() != 0)
                in.readByte();
            in.close();
        }
    }

    执行该程序,当中使用的data.txt文件大小为5.4M,在我的电脑上的输出为:

    readWithBufferedInputStream use time:8775
    readWithoutBufferedInputStream use time:18487

    显然使用了BufferedInputStream效率高了不少。

    3、java1.5以后为了方便文件的输入,加入了一个PrintWrite过滤器,它封装了BufferedWriter,并且能够接受String类型的文件名称。所以能够精简代码。

    import java.io.*;
    public class FileOutPut {
        public static void main(String[]args) throws Exception{
            BufferedReader in=new BufferedReader(new FileReader("data.txt"));
            PrintWriter out=new PrintWriter("data1.txt");
            String s;
            long start=System.currentTimeMillis();
            while((s=in.readLine())!=null){
                out.println(s);//用readLine读取文件时,每一行的回车符会被去掉。所以写入文件的时候要把回车符写回去
            }
            System.out.println("use time:"+(System.currentTimeMillis()-start));
            in.close();
            out.close();
        }
    }

    执行文件同一时候能够发现,相同是一样大的data.txt文件,读出并写出速度很快。这个得益于缓存。

    4、因为之前的方法往文件中面写入的是字节或字符,没有办法存储一些基本类型。所以要使用DataOutputStream/DataInputStream。

    import java.io.*;
    
    public class ReadAndWriteBaseType {
        public static void main(String[] args) throws Exception {
    
            DataOutputStream out = new DataOutputStream(new FileOutputStream(
                    "data1.txt"));
            out.writeUTF("This a String");// 写入字符串要用writeUTF();
            out.writeInt(5);
            out.writeFloat(5.4f);
            out.close();
    
            DataInputStream in = new DataInputStream(new FileInputStream(
                    "data1.txt"));
    
            System.out.println(in.readFloat());
            System.out.println(in.readInt());
            System.out.println(in.readUTF());// 读出字符串要用readUTF();
            in.close();
        }
    }   

    5、使用RandomAccessFile进行读写文件有点相似DataOutputStream/DataInputStream。都须要指定数据类型。但RandomAccessFile在创建对象的时候须要确定对文件的操作类型,r/w/rw分别表示仅仅读,仅仅写,读和写。Seek()方法能够到处移动。在文件的任何位置改动内容

    import java.io.*;
    
    public class UsingRandomAccessFile {
        public static void main(String[] args) throws Exception {
            RandomAccessFile rf = new RandomAccessFile("data1.txt", "rw");
            rf.writeInt(5);
            rf.writeInt(10);
            rf.writeInt(15);
            rf.writeInt(24);
            rf.close();
    
            rf = new RandomAccessFile("data1.txt", "r");
            System.out.println(rf.readInt());
            System.out.println(rf.readInt());
            System.out.println(rf.readInt());
            System.out.println(rf.readInt());
            rf.close();
    
            rf = new RandomAccessFile("data1.txt", "rw");
            rf.seek(0);// 把指针指向文件开头
            rf.writeInt(-1);// 把前两个字节改成-1
            rf.seek(0);
            System.out.println(rf.readInt());
            System.out.println(rf.readInt());
            System.out.println(rf.readInt());
            System.out.println(rf.readInt());
            rf.close();
    
        }
    }

    6、把标准输入用BufferedReader包装并获取键盘输入

    public class Systemin {
        public static void main(String[] args) throws Exception {
            // System.in为InputStream类型。要通过InputStreamReader将其转换成Reader
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String s;
            while ((s = in.readLine()) != null) {
                System.out.println(s);
            }
        }
    }

    6、重定向。把控制台输出、错误输出定向到文件,可用来写日志文件

    import java.io.*;
    
    public class Redirect {
    
        public static void main(String[] args) throws Exception {
            OutputStream console = System.out;
            PrintStream out = new PrintStream(new BufferedOutputStream(
                    new FileOutputStream("data1.txt")));
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    new FileInputStream("data.txt")));
            System.setOut(out);// 把输出重定向到out
            System.setErr(out);// 把错误信息重定向到out
            String s;
            while ((s = in.readLine()) != null)
                System.out.println(s);// 输出被定向到out,所以不会在控制台输出
            out.close();
            in.close();
        }
    
    }
  • 相关阅读:
    IIS与ASP.NET中的线程池
    IIS与ASP.NET中的队列
    让ASP.NET OutputCache使用http.sys kernel-mode cache
    微软的坑:Url重写竟然会引起IIS内核模式缓存不工作
    实际案例:在现有代码中通过async/await实现并行
    困扰多日的C#调用Haskell问题竟然是Windows的一个坑
    C#调用haskell遭遇Attempted to read or write protected memory
    经过实际验证的C#调用Haskell的方法
    Haskell中cabal install glib遇到的问题
    Haskell ghci中调用pandoc的API进行markdown转换
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7249097.html
Copyright © 2011-2022 走看看