EchoDemo's Blogs

Java中的输入输出流

1、流的概念和分类

(1)流的概念

流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件、内存或是网络连接。同理,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据就好像在这其中“流动”一样。

(2)流的分类

a、流按其流向分为“输入流”和“输出流”。

b、流按数据传输单位分为“字节流”和“字符流”。“字节流”用来读写8位二进制的字节,“字符流”用来读写16位二进制字符。

c、流按功能分为“节点流”和“过滤流”。“节点流”用于直接操作目标设备的流,例如:磁盘或一块内存区域。“过滤流”是对一个已存在的流的链接和封装,通过对数据进行处理,为程序提供功能强大、灵活的读写功能。

2、InputStream和Outputstream抽象类

字节流类用于向字节流读写8位二进制的字节。一般的,字节流类主要用于读写诸如图像或声音等的二进制数据。字节流类以InputStream和OutputStream为顶层类。他们都是抽象类。InputStream中定义的方法有:

public abstract int read();//从输入流中读取数据的下一个字节

public int read(byte[] b);//从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中

public int read(byte[] b ,int off ,int len);//将输入流中最多len个数据字节读入byte数组

public long skip(long n);//跳过或者丢弃此输入流中数据的n个字节

public int available();//返回从该输入流中可以读取的字节数的估计值,而不会被下一次调用此输入流的方法阻塞

public void close();//关闭输入流并释放与该流关联的所有系统资源

OutputStream抽象类所有方法返回void值,在出错情况下抛IOException异常。需要定义OutputStream子类的应用,OutputStream必须至少提供一个写入一个字节输出的方法。OutputStream中定义的方法:

public abstract void write(int b);//将指定的字节写入此输出流。 

public void write(byte[] b);//将b.length个字节从指定的byte数组写入此输出流

public void write(byte[] ,int off ,int len);//从指定的字节数组写入len个字节,从偏移off开始输出到此输出流。

public void flush();//刷新此输出流并强制任何缓冲的输出字节被写出。

public void close();//关闭输出流并释放与该流关联的所有系统资源

3、FileInputStream和FileOutputStream(它们分别是InputStream和OutputStream类的子类)

(1)每个抽象类都有多个具体的子类,这些子类对不同的外设进行处理,例如磁盘文件,网络连接,甚至是内存缓冲区。FileInputStream类表示能从文件读取字节的InputStream类。其常用的构造方法有:FileInputStream(String filepath);FileInputStream(File fileObj);FileOutputStream类表示能向文件写入字节的OutputStream类。其常用的构造方法有:FileOutputStream(String filepath);FileOutputStream(File fileObj);FileOutputStream(String filePath,boolean append);

(2)举例说明

package com.iotek.inputoutputstream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileInputStreamOutputStreamDemo {

    public static void main(String[] args) {
        try {//这里不管是读取文件,还是写入文件,都应该是文件,而不是文件夹。
            FileCopyUtil.copyFile(new File("G:\\bookmarks_5_8_18.html"), new File("F:\\test\\test.html"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class FileCopyUtil{
    public static void copyFile(File src,File dst) throws IOException{    
        FileInputStream fileInputStream = new FileInputStream(src);
        FileOutputStream fileOutputStream = new FileOutputStream(dst);
        long time1 = System.currentTimeMillis();
        /*int data = -1;
        while((data = fileInputStream.read())!=-1){
            fileOutputStream.write(data);
        }*/


        byte[] buf = new byte[1024*1024];//创建一个1M大小的缓冲区,用来存放输入流中的字节数据
        int len = 0;//用来保存实际读到的字节数
        while((len = fileInputStream.read(buf))!=-1){
            fileOutputStream.write(buf, 0, len);//使用缓冲区对文件的进行读写操作会大大提高读写的速度
        }
        fileOutputStream.close();
        fileInputStream.close();
        long time2 = System.currentTimeMillis();
        System.out.println("复制完成,一共花费:" + (time2-time1) + "毫秒");
    }
}

4、ByteArrayInputStream和ByteArrayOutputStream

(1)ByteArrayInputStream是把字节数组当成源的输入流,其内部包含一个内部缓冲区,且调用close()方法关闭ByteArrayInputStream无效。它有两个构造方法,每个都需要一个字节数组提供数据源:ByteArrayInputStream(byte array[]);ByteArrayInputStream(byte array[],int start,int numBytes);ByteArrayOutputStream是把字节数组当作目标的输出流,它也有两个构造方法:ByteArrayInputStream();ByteArrayOutputStream(int numBytes);

(2)举例说明

package com.iotek.inputoutputstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteArrayInputOutputStream {

    public static void main(String[] args) throws IOException {
        /*String string = "Hello,shanghai!";
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(string.getBytes());
        int data = -1;
        while((data=byteArrayInputStream.read())!=-1){
            System.out.print((char)data);
        }
        byteArrayInputStream.close();//这里的关闭时无效的,因为没有调用操作系统底层的函数。*/

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byteArrayOutputStream.write(97);
        byteArrayOutputStream.write(65);
        byteArrayOutputStream.write("hello,world!".getBytes());
        byte[] buff = byteArrayOutputStream.toByteArray();
        for(byte b:buff){
            System.out.print((char)b);
        }
        FileOutputStream fileOutputStream = new FileOutputStream("f:\\test\\a.txt",true);//true表示可以追加
        byteArrayOutputStream.writeTo(fileOutputStream);//把ByteArrayOutputStream内部缓冲区中的数据写到对应的文件输出流中
        byteArrayOutputStream.close();//这里的关闭同上
    }
}
🐶 您的支持将鼓励我继续创作 🐶
-------------本文结束感谢您的阅读-------------