Java里的IO输入输出流

       Java中的输入输出流是Java的高级特性之一,其主要分为输入流和输出流,按照输入输出格式又分为字节流和字符流,按照这个规则拓展又出现了多个子类,具体可以参照下图。


1、字节流和字符流的主要区别

       字符流主要是Reader和Writer,字节流主要是InputStream和OutPutStream。这其中的最要区别在于,字符流是以字符的形式进行传输,而字节流的传输是按照字节来进行传输的,一个字节byte有8位,值在-128~127之间。而一个字符则按照编码方式的不同有所差异,目前主流的Unicode编码,无论是中文还是英文都是占用的2个字节。字符的本质上是按照一定编码规则组成的字节。

       因此,我们在使用字符流和字节流的时候就可以知道何时何地怎么使用了,通常我们在传输MP3、视频、音乐、图片等格式的文件时,就应该使用字节流,而在传输文本、固定格式文件时一般来说时候Reader、Writer这样的字符流。

2、Java IO字节流输入输出InputStream、OutputStream

       我们可以通过一个小栗子来举例说明字节输入输出流:

package com.dingtao.test;

import java.io.*;

public class Solution {


    public static void main(String[] args) throws IOException {
        String s1 = "hello outputStream~~";
        File file = new File("d://outputStream.txt");
        OutputStream outputStream = new FileOutputStream(file);
        try {
            outputStream.write(s1.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            outputStream.close();
        }
    }
}

输出为:


     这里执行完之后,就可以在d盘的根目录下找到outputStream .txt文件,里面内容是我们输入的hello outputStream~~,这里演示的就是通过outputStream将String输出到一个txt文件中去,要注意的是,这里一定要使用.getBytes()方法将String转化为byte字节流才可以使用write方法。

同理 InputStream,我们可以使用它把 文件里的内容输出到java程序中去,具体代码:

package com.dingtao.test;

import java.io.*;

public class Solution {


    public static void main(String[] args) throws IOException {
//        String s1 = "hello outputStream~~";
//        File file = new File("d://outputStream.txt");
//        OutputStream outputStream = new FileOutputStream(file);
//        try {
//            outputStream.write(s1.getBytes());
//        } catch (IOException e) {
//            e.printStackTrace();
//        }finally {
//            outputStream.close();
//        }
        File file = new File("d://outputStream.txt");
        InputStream inputStream = new FileInputStream(file);
        int flen = (int) file.length();
        byte[] b = new byte[flen];
        int len =0;
        try {
             len = inputStream.read(b);
        }catch (IOException e1){
            e1.printStackTrace();
        }finally {
            inputStream.close();
        }
        System.out.println(len);
        System.out.print(new String(b));
    }
}

输出为:


        从这里就可以看出,我们利用输入流InputStream将文件中的内容输出到了程序中,这里输出的是一个byte[]数组,需要通过new String()构造成一个字符串输出既可。inputStream.read(b)的输出是该输入流的长度length。

3、字符输入输出流Reader、Writer

       上个小节我们通过字节输入输出流学习了InputStream和OutPutStream,这里我们来看看Reader和Writer。首先还是来个小栗子。

package com.dingtao.test;

import java.io.*;

public class Solution {


    public static void main(String[] args) throws IOException {
        File file = new File("D://writer.txt");
        Writer writer = new FileWriter(file);
        writer.write("你好呀,赛利亚");
        writer.close();
    }
}

结果为:


       这里就可以看到,使用方法基本一致,除了中间用于融合File类和Writer的类FileWriter类不一样之外,其他基本一致,这里的汉子一样被写入到了文件中去。

       再将该文件,Reader读取到Java内存中去:

package com.dingtao.test;

import java.io.*;

public class Solution {


    public static void main(String[] args) throws IOException {
//        File file = new File("D://writer.txt");
//        Writer writer = new FileWriter(file);
//        writer.write("你好呀,赛利亚");
//        writer.close();
        File file = new File("D://writer.txt");
        Reader reader = new FileReader(file);
        int flen = (int) file.length();
        char[] c = new char[flen];
        int rlen = reader.read(c);
        System.out.println(rlen);
        System.out.println(new String(c));
    }
}

输出为:


4、文件随机读取RandomAccessFile

        上面的两种方法,都只能从文件一开始的开头进行读取,一旦我想要读取文件中间的某个信息,就会浪费大量的I/O资源,因此这里就诞生了随机读取RandomAccessFile,这个类可以帮助我们直接从某个地方开始读取信息。具体代码如下:

package com.dingtao.test;

import java.io.*;

public class Solution {


    public static void main(String[] args) throws IOException {
        File file = new File("D://writer.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        randomAccessFile.seek(4);
        long l = randomAccessFile.getFilePointer();
        byte[] b = new byte[(int) file.length()];
        int rlen = randomAccessFile.read(b);
        System.out.println(rlen);
        System.out.println(new String(b));

    }
}

具体结果如下:


      这里会乱码的主要原因是在于,char字符类型通过Unicode编码是两个字节组成的,所以就会产生乱码。再看看通过这个进行特定节点的写入。

package com.dingtao.test;

import java.io.*;

public class Solution {


    public static void main(String[] args) throws IOException {
        File file = new File("D://writer.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        randomAccessFile.seek(5);
        long l = randomAccessFile.getFilePointer();
        byte[] b = "嘿嘿嘿".getBytes();
        randomAccessFile.write(b);
        System.out.println(randomAccessFile.getFilePointer());
        randomAccessFile.close();
    }
}

结果是:


如果所示,这段话插入到了seek(5)的地方并保存了下来。


5、Java缓冲输入输出流

       Java的缓冲输入输出流的主要应用场景在于,I/O的速度和CPU的速度不匹配的原因造成的,所以通过缓存,一次性将大量的数据刷入内存或者保存在本地上。具体可以举例看下以下的代码,使用BufferReader包装以下既可:

     

package com.dingtao.test;
import java.io.*;

public class Solution {

    public static void main(String[] args) throws IOException {
        File file = new File("D://writer.txt");
        Reader reader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(reader);
        char[] c = new char[(int) file.length()];
        int blen = bufferedReader.read(c);
        bufferedReader.close();
        reader.close();
        System.out.println(blen);
        System.out.println(new String(c));
    }
}

输出为:


至于其他类型的BufferInputStream、BufferOutputStream、BufferWriter在这里就不一一举例了。


6、Java管道IO

       PipedInputStream、PipedOutputStream主要用户进程间通信,具体例子如下:

package com.dingtao.test;
import java.io.*;

public class Solution {

    public static void main(String[] args) throws IOException {

        PipedInputStream pipedInputStream = new PipedInputStream();
        PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream);

        Thread  t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    pipedOutputStream.write("hello,i am pipedOutputStream".getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        pipedOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    byte[] b = new byte[1024];
                        pipedInputStream.read(b);
                        System.out.println(new String(b));
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        pipedInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        t1.start();
        t2.start();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值