IO总结

IO流

IO流主要分为字符流和字节流,下面给出字符流和字节流的结构图:

字符流

字符流主要对纯文本进行操作。Java提供了Reader和Writer两个专门操作字符流的类。

Reader和Writer是抽象类,要使用此类,需用子类

字符输出流Writer:

private static void demo1() throws IOException {
        File f = new File("d:" + File.separator + "test.txt");
        Writer out = new FileWriter(f);
        String str = "HelloWorld";
        out.write(str);
        out.close();
    }

文件没有可以自动创建,若向文件中添加内容,只需要向FileWriter 中添加      true,

即Writer out = new FileWriter(f,true);

字符输入流Reader:

File f = new File("d:" + File.separator + "test.txt");
        Reader reader = new FileReader(f);
        char[] c = new char[1024];
        int len = reader.read(c);
        reader.close();
System.out.println("内容为:" + new String(c, 0, len));

如果不知道要输入的数据的长度,使用循环方式进行内容读取:

private static void demo2() throws Exception {
        File f = new File("d:" + File.separator + "test.txt");
        Reader reader = new FileReader(f);
        int len = 0;
        char[] c = new char[1024];
        int temp = 0;
        while ((temp = reader.read()) != -1) {
            c[len] = (char) temp;
            len++;
        }
        reader.close();
        System.out.println("内容为:" + new String(c, 0, len));
}

字节流

字节输入流InputStream:

// 有大量空格,浪费空间
    private static void demo1() throws Exception {
        File f = new File("d:" + File.separator + "test.txt");// 路径不存在会抛出异常
        InputStream input = new FileInputStream(f);
        byte[] b = new byte[1024];// 内容不能超过1024
        input.read(b);
        input.close();
        System.out.println("内容为:" + new String(b));// 把byte[]变为字符串输出,后有大量空格
}

修改代码,用len接收input.read(b);即int len = input.read(b);

打印new String(b,0,len);但是这样去除了空格,空间还是浪费,修改代码

byte[] b = new byte[(int) f.length()]; 这样数组大小由文件决定,解决了空间浪费的问题,但是要知道输入的内容有多大。若输入内容大小未知,需要通过判断是否读到文件末尾的方式来读取文件。

private static void demo4() throws Exception {
        File f = new File("d:" + File.separator + "test.txt");
        InputStream input = new FileInputStream(f);
        int len = 0;// 用于记录读取的数据个数
        byte[] b = new byte[1024];
        int temp = 0;// 接收读取的内容
        while ((temp = input.read()) != -1) {
            b[len] = (byte) temp;
            len++;
        }
        input.close();

        System.out.println("内容为:" + new String(b, 0, len));
}

字节输出流:OutputStream

若文件不存在,可以自动创建。

private static void demo5() throws Exception {
        File f = new File("d:" + File.separator + "test.txt");
        OutputStream out =new FileOutputStream(f);
        String str = "Hello World";
        byte[] b =str.getBytes();
        out.write(b);
        out.close();
}

追加新内容,只需修改代码OutputStream out =new FileOutputStream(f,true);即可。

字符流与字节流的区别:字节流不会用到缓冲区,是对文本进行直接操作,而字符流操作时需要用到缓冲区,通过缓冲区操作文件。

注意,程序最后要关闭流,字节流不关闭,内容可以输出,但字符流不关闭的话,最后一段内容存在于缓冲区中,无法读取出来,造成内容失真。如果想在不关闭流的情况下,将字符流的内容全部输出,可以用Writer中的flush()强制清空缓冲区。

转换流OutputStreamWriter与InputStreamReader

结构图:

字节输出流变字符输出流:

private static void demo6() throws Exception {
        File f = new File("d:" + File.separator + "test.txt");
        Writer out =new OutputStreamWriter(new FileOutputStream(f));
        out.write("hello world");
        out.close();
}

字节输入流变为字符输入流:

private static void demo7() throws Exception {
        File f = new File("d:" + File.separator + "test.txt");
        Reader reader = new InputStreamReader(new FileInputStream(f));
        char[] c = new char[1024];
        int len = reader.read(c);
        reader.close();
        System.out.println(new String(c,0,len));
}

内存操作流

内存操作流一般在生成一些临时信息才会用到,如果将这些临时信息保存在文件中,则代码执行后肯定还要删除这个临时文件会比较麻烦,这个时候用内存操作流最合适。

private static void demo8() throws IOException {
        String str = "HELLOWORLD";
        ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes());
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int temp = 0;
        while ((temp = bis.read()) != -1) {
            char c = (char) temp;
            bos.write(Character.toLowerCase(c));
        }
        String newStr = bos.toString();
        bis.close();
        bos.close();
        System.out.println(newStr);
}

管道流

package guandaoliu;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipidDemo {

    public static void main(String[] args) {
        Send s = new Send();
        Receive r = new Receive();
        try {
            s.getPos().connect(r.getPis());
        } catch (IOException e) {

            e.printStackTrace();
        }
        new Thread(s).start();
        new Thread(r).start();
    }

}

class Send implements Runnable {
    private PipedOutputStream pos = null;

    public Send() {
        this.pos = new PipedOutputStream();

    }

    @Override
    public void run() {
        String str = "hello world";
        try {
            this.pos.write(str.getBytes());
        } catch (IOException e) {

            e.printStackTrace();
        }
        try {
            this.pos.close();
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

    public PipedOutputStream getPos() {
        return pos;
    }
}

class Receive implements Runnable {
    private PipedInputStream pis = null;

    public Receive() {
        this.pis = new PipedInputStream();

    }

    @Override
    public void run() {
        byte[] b = new byte[1024];
        int len = 0;
        try {
            len = pis.read(b);
        } catch (IOException e) {

            e.printStackTrace();
        }
        try {
            this.pis.close();
        } catch (IOException e) {

            e.printStackTrace();
        }
        System.out.println("接收的内容为:" + new String(b, 0, len));

    }

    public PipedInputStream getPis() {
        return pis;
    }

}

BufferedReader类

BufferedReader类用于从缓冲区读取内容,所有的输入字节数据都放在缓冲区中。BufferedReader定义的构造方法只能接收字符输入流的实例,所以必须使用字符输入流和字节输入流的转换类InputStreamReader将字节输入流System.in变为字符流。

BufferedReader buf =new BufferedReader(new InputStreamReader(System.in));

常用方法:

public BufferedReader(Reader in)     构造      接收一个Reader的实例

public String readLine()throws IOException  普通   一次性从缓冲区将内容读出来。

原文地址:https://www.cnblogs.com/songzongyuan-java/p/9427180.html