欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

I/O之字节流

程序员文章站 2024-03-04 21:31:00
...

在Java中把一组有序的数据称为流,根据操作类型分为输入流和输出流。程序从输入流读取数据,向输出流写入数据。根据数据单元分为字节流和字符流。
字节数入流:java.io.InputStream;字节输出流:java.io.OutputStream;字符输入流:java.io.Reader;字符输出流:java.io.Writer。
I/O之字节流
一.InputStream抽象类,不能被实例化

InputStream类提供了一系列的方法用来读取数据:
(1) int read() 从输入流读取数据,有三种重 载形式:
int read() 从输入流读取一个八位的字节,把它转换为0~255的整数,返回这一整数。
int read(byte[] b) 从输入流读取若干字节,把它们保存到参数b指定的字节数组中,返回值表示读取的字节数。
int read(byte[] b,int off,int len) 从输入流读取若干字节,把它们保存到参数b指定的字节数组中,参数off是指在字节数组中指定的开始保存的位置,len是指读取的字节数。
(2) void close() 关闭输入流
(3) int available() 返回可以从输入流中读取的字节数目。
(4) skip(long n) 从输入流中跳过参数n指定数目的字节。
(5) boolean markSupport(),void mark(int readLimit),void reset() 可以从输入流中进行重复读入数据。
以上是InputStream共有的方法。

1.1ByteArrayInputStream 字节数组输入流:
从内存的字节数组中读取数据.
construct—
(1) ByteArrayInputStream(byte[] buf):参数buf指定字节数组类型的数据源。
(2) ByteArrayInputStream(byte[] buf,int offset,int length):参数buf指定字节数组类型的数据源,参数offset指定从数组中开始读取数据的位置,length指定conf数组中读取的字节数.
method—
实现了InputStream所有的方法.

import java.io.ByteArrayInputStream;
import java.io.IOException;

public class ByteArrayTester {

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

        //定义一个byte数组
        byte[] buffer=new byte[]{2,15,67,-1,-9,9};

        //定义一个输入流
        ByteArrayInputStream inputStream=new ByteArrayInputStream(buffer, 1, 4);

        //从输入流读取数据
        int data=inputStream.read();

        //输出到控制台
        while(data!=-1){
            System.out.println(data+" ");
            data=inputStream.read();
        }
        inputStream.close();
    }
}
输出 15 67 255 247

1.2FileInputStream 文件输入流:
从文件中读取数据.
construct—
(1) FileInputStream(File file):参数file指定文件数据源;
(2) FileInputStream(String name):参数name指定文件数据源,name中包含文件路径信息.
method—
实现了InputStream部分方法.

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

public class FileInputStreamTester {

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

        //定义一个文件输入流
        FileInputStream inputStream=new FileInputStream("G:\\Test.txt");

//      //输出到控制台
//      int data=inputStream.read();
//      while(data!=-1){
//          System.out.print(data+" ");
//          data=inputStream.read();
//      }

        //将test.txt的数据复制到out.txt中
        FileOutputStream outputStream=new FileOutputStream("G:\\out.txt");
        int SIZE=1024;
        byte[] buff =new byte[SIZE];    //创建字节数组缓冲区
        int len=inputStream.read(buff);    //把test.txt的数据读入到buff中
        while(len!=-1){
            outputStream.write(buff,0,len);   //把buff中的数据写入到out.txt中
            len=inputStream.read(buff);
        }
        //关闭
        inputStream.close();
        outputStream.close();
    }
}

1.3PipedInputStream 顺序输入流:
可以将几个输入流串联在一起合并为一个输入流.
construct—
SequenceInputStream(Enumeration e):在枚举类型的参数e中包含若干个需要被串联的输入流.
SequenceInputStream(InputStream s1,InputStream s2):参数s1,s2代表两个需要串联的输入流.
method—
实现了InputStream中的部分方法。

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;

public class SequenceTester {

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

        //定义两个字节数组输入流
        InputStream inputStream1=new ByteArrayInputStream("你".getBytes());    //返回你的GBK编码
        InputStream inputStream2=new ByteArrayInputStream("好".getBytes());

        //用SequenceInputStream将上面的两个输入流连接起来,使其顺序输出
        InputStream inputStream=new SequenceInputStream(inputStream1, inputStream2);

        //输出
        int data;
        while((data=inputStream.read())!=-1)
            System.out.print(data+" ");
        inputStream.close();   //inputStream1 inputStream2 随之也会关闭
    }
}

1.4FilterInputStream 过滤输入流:
是一种用于扩展输入流功能的装饰器,其本身没有什么作用,有作用的是它的一些子类,如:
DataInputStream,BufferedInputStream,PushbackInputStream.
1.4.1 BufferedInputStream:
覆盖了被装饰的输入流的读数据的行为,利用缓冲区提高读数据的效率。
construct—
BufferedInputStream(InputStream in):参宿in是指被装饰的输入流;
BufferedInputStream(InputStream in,int size):参宿in是指被装饰的输入流,参数size是指缓冲区大小。
下面利用缓冲方式进行复制和非缓冲方式进行复制两种方式进行对比。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Demo2 {

    /**
     * 缓冲方式进行复制
     * @throws Exception
     */
    public static void bufferedStream() throws Exception{

        //定义输入流
        BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("G:\\Java\\Java笔记\\详解java类的生命周期.doc"));

        //定义输出流
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("G:\\Java\\Java笔记\\复制的详解java类的生命周期.doc"));

        int b=0;
        long startTime =System.currentTimeMillis();   //开始的时间
        while((b=bufferedInputStream.read())!=-1){
            bufferedOutputStream.write(b);
        }
        long endTime =System.currentTimeMillis();     //结束的时间
        //关闭
        bufferedInputStream.close();
        bufferedOutputStream.close();

        System.out.println("缓冲方式所花费的时间为:"+(endTime-startTime));
    }

    public static void main(String[] args) throws Exception {
        bufferedStream();
    }
}
//缓冲方式所花费的时间为:38
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Demo1 {

    /**
     * 非缓冲方式进行复制
     * @throws Exception
     */
    public static void stream() throws Exception{

        //定义输入流
        InputStream inputStream=new FileInputStream("G:\\Java\\Java笔记\\详解java类的生命周期.doc");

        //定义输出流
        OutputStream outputStream=new FileOutputStream("G:\\Java\\Java笔记\\复制的详解java类的生命周期.doc");

        int b=0;
        long startTime =System.currentTimeMillis();   //开始的时间
        while((b=inputStream.read())!=-1){
            outputStream.write(b);
        }
        long endTime =System.currentTimeMillis();     //结束的时间
        //关闭
        inputStream.close();
        outputStream.close();

        System.out.println("非缓冲方式所花费的时间为:"+(endTime-startTime));
    }

    public static void main(String[] args) throws Exception {
        stream();
    }
}
//非缓冲方式所花费的时间为:552

1.4.2 color=”#dd0000”>DataInputStream:
实现了DataInput接口,用于读取基本类型数据。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class FormatDataIO {

    public static void main(String[] args) throws IOException {
        FileOutputStream outputStream=new FileOutputStream("G:\\Test.txt");
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);   //装饰文件输出流
        DataOutputStream dataOutputStream =new DataOutputStream(bufferedOutputStream);    //装饰带缓冲流

        dataOutputStream.writeByte(-12);
        dataOutputStream.writeLong(12);
        dataOutputStream.writeChar('1');
        dataOutputStream.writeUTF("好");

        dataOutputStream.close();

        InputStream inputStream=new FileInputStream("G:\\Test.txt");
        BufferedInputStream bufferedInputStream=new BufferedInputStream(inputStream);
        DataInputStream dataInputStream=new DataInputStream(bufferedInputStream);

        System.out.println(dataInputStream.readByte()+" ");
        System.out.println(dataInputStream.readLong()+" ");
        System.out.println(dataInputStream.readChar()+" ");
        System.out.println(dataInputStream.readUTF()+" ");

        dataInputStream.close();

    }
}
//-12 12 1

二.OutputStream抽象类,不能被实例化

method—
write(int):写入一个字节到stream中
write(byte[])写入一个byte数组到stream中
write(byte[],int,int):把byte数组中从offset开始处写入长度为len的数据
close():关闭流,这个是在操作完stream之后必须要调用的方法
flush():通过带缓冲区的输出流写数据时,数据先保存在缓冲区,积累到一定程度才能真正写到输出流中。
2.1 ByteArrayOutputStream 字节数组输出流:
向内存中的字节数组写入数据。
construct—
(1)— ByteArrayOutputStream() 创建一个新的字节数组输出流。
(2)— ByteArrayOutputStream(int) 创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量。

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

public class ByteArrayOutputStreamTester {

    public static void main(String[] args) throws UnsupportedEncodingException, IOException {
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        byteArrayOutputStream.write("你好".getBytes("UTF-8"));

        byte[] buff=byteArrayOutputStream.toByteArray();   //获得字节数组
        byteArrayOutputStream.close();

        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(buff);
        int len=byteArrayInputStream.available();
        byte[] buffin=new byte[len];
        byteArrayInputStream.read(buffin);  //把buff中的数据写到buffin中去
        byteArrayInputStream.close();

        System.out.println(new String(buffin,"UTF-8"));   //输出你好
    }
}

2.2FileOutputStream 文件输出流:
向文件写数据。
construct—
FileOutputStream(File file);
FileOutputStream(String name);
FileOutputStream(String name,boolean append);
注:创建FileOutputStream实例时,如果相应文件不存在,会自动创建一个空的文件。如果file或name表示的文件路径存在,但是代表一个文件目录会抛出FileNotFoundException。

2.3FilterOutputStream 过滤输出流:
与FilterInputStream一样。本身没什么用处,其子类有用。
2.3.1 BufferedOutputStream:带有缓冲区的stream
constructor—
BufferedOutputStream(OutputStream):使用OutputStream参数初始化BufferedOutputStream类
BufferedOutputStream(OutputStream,int):在初始化实例的时候指定缓冲区的大小
method—
实现了FilterOutputStream中的部分方法

2.3.2 DataOutputStream:具有格式化的OutputStream
constructor—
DataOutputStream(OutputStream):使用OutputStream参数来初始化DataOutputStream实例
method—
实现了FilterOutputStream中的部分方法
writeInt,writeFloat,writeDouble….能够给直接向stream中写入基本类型的方法

2.3.3 PrintStream:直接输出到控制台中:我们最熟悉的就是System.out他就是一个PrintStream
constructor—
PrintStream(OutputStream):使用OutputStream参数来实例化PrintStream
method—
实现了FilterOutputStream中的部分方法
print()有多个重载的方法,8中基本类型和String类型,同时他还可以进行格式化输出。