Java IO之简单输入输出

Java中的IO分为两个部分,以InputStream和Reader为基类的输入类,以OutputStream和Writer为基类的输出类。其中InputStream和OutputStream以字节为单位进行IO,而Reader和Writer以字符为单位。java

除了输入输出,还有一系列类库称为Filter,或成为装饰器。对于输入可用FilterInputStream和FilterReader的派生类,输出可用FilterOutputStream和FilterWriter的派生类,其中FilterInputStream和FilterOutputStream以字节为单位,FilterReader和FilterWriter以字符为单位。缓存

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

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

过滤器(Filter)

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

FilterInputStream的派生类:指针

这里写图片描述

FilterOutputStream的派生类:日志

这里写图片描述

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

这里写图片描述

对于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);

综合示例

一、打开一个文件,并把其中的内容逐行输出的屏幕上。为了提升效率,这里将使用第一种过滤器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();
    }
}

二、从文件中按字节读取内容,须要用到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效率高了很多。

三、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文件,读出并写出速度很是快,这个得益于缓存。

四、因为以前的方法往文件里面写入的是字节或字符,没有办法存储一些基本类型,因此要使用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();
    }
}

五、使用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();

    }
}

六、把标准输入用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);
        }
    }
}

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

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();
    }

}
相关文章
相关标签/搜索