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();
        }
    
    }
  • 相关阅读:
    C# 图片与Base64的相互转化
    LeetCode 303. Range Sum Query – Immutable
    LeetCode 300. Longest Increasing Subsequence
    LeetCode 292. Nim Game
    LeetCode 283. Move Zeroes
    LeetCode 279. Perfect Squares
    LeetCode 268. Missing Number
    LeetCode 264. Ugly Number II
    LeetCode 258. Add Digits
    LeetCode 257. Binary Tree Paths
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7249097.html
Copyright © 2011-2022 走看看