Java IO----字节流

类图

在这里插入图片描述

InputStream常用的类&方法

常用类含义
InputStreamInputStream抽象类是字节输入流所有类的超类,它以字节为单位从数据源中读取数据
FileInputStream以字节为单位从文件中读取数据
FilterInputStream封装其它的输入流,并为它们提供额外的功能
BufferedInputStream给输入流提供缓冲功能,提高读取效率
DataInputStream装饰其它输入流,它允许应用程序以与机器无关方式从底层输入流中读取 Java基本数据类型
PushBackInputStream可以把读取进来的某些数据重新回退到输入流的缓冲区之中
ObjectInputStream从输入流读入对象,读取对象信息
PipedInputStream与其它线程共用的管道中读取数据
SequenceInputStream合并流
StringBufferInputStream以字节为单位从字符串中读取数据
ByteArrayInputStream在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区中
常用方法含义
public abstract int read() throws IOExecption该方法用于从输入流中读取数据的下一个字节,返回读到的字节值,若遇到流的末尾,返回-1
public int read(byte[] b) throws IOExecption该方法用于从输入流中读取b.length个字节的数据,并将数据存储到缓冲区数组b中,返回的是实际读到的字节数
public int read(byte[] b,int off,int len) throws IOExecption该方法用于从输入流中读取len个字节的数据,并从数组b的off位置开始写入到这个数组中
public void close() throws IOExecption关闭此输入流,并释放与此输入流相关联的所有系统资源
FileInputStream 简介

FileInputStream是从文件中读取数据,所以我们让它从txt文件中读取数据,然后打印

public class FileInputStreamTest {
    public static void main(String[] args) throws Exception {
        //1.得到数据文件
        String filePath = "E:\\ExampleTest\\TestText.txt";
        File file = new File(filePath);
       	try {
	        //2.创建输入流
	        InputStream inputStream = new FileInputStream(file);
	        //3.循环读取文件内容,输入流中将最多bytes.length个字节的数据读入一个byte数组中,
	        //返回的是读取到的字节数。当文件读取到结尾时返回 -1,循环结束。
	        byte[] bytes = new byte[1024];
	        int length = 0;
	        while ((length = inputStream.read(bytes)) != -1) {
	            System.out.println("Length is " + length);
	            System.out.println(new String(bytes, 0, length));
	        }
         } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //4.关闭输入流
        inputStream.close();
    }
}

如果文件有两个字节内容,则读取时将两个字节读取到bytes中,length等于2,然后再读取一次,因为到达文件末尾,则返回-1,while循环退出,关闭输入流,程序结束

FilterInputStream简介

FilterInputStream 只是简单地重写那些将所有请求传递给所包含输入流的 InputStream 的所有方法。FilterInputStream 的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。从FilterInputStream类注释可以看出,需要关注的是FilterInputStream的子类,BufferedInputStream,DataInputStream,PushBackInputStream。FliterInputStream不能直接创建,它的构造方法是protected

BufferedInputStream简介

带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能。从InputStream中读取数据时,一般都会是磁盘io,或者网络io,这都是耗费大量时间的操作,比如我们现在从文件读取20个字节,过一会又从文件读取20个字节,这就是两次io,浪费资源,有了BufferedInputStream,就解决这个两次io的问题,输入流在read时,干脆多读一部分数据进来,放在内存里,等你每次操作流的时候,读取的数据直接从内存中就可以拿到,这就减少了io次数,提升效率。

DataInputStream&DataOutputStream简介

DataInputStream 是用来装饰其它输入流,DataOutputStream是用来修饰其他输出流,它允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用DataOutputStream(数据输出流)写入数据然后由DataInputStream(数据输入流)读取数据

public class DataInputStreamTest {
    public static void main(String[] args) throws Exception{
        //1.得到数据文件
        String filePath = "E:\\ExampleTest\\TestText.txt";
        File file = new File(filePath);
        try {
	        file.createNewFile();
	        //2.创建输出流,写入Java基本类型数据
	        DataOutputStream bufferedOutputStream = new DataOutputStream(new FileOutputStream(file));
	        bufferedOutputStream.writeInt(1);
	        bufferedOutputStream.writeDouble(3.14);
	        bufferedOutputStream.writeBoolean(true);
	        bufferedOutputStream.writeUTF("Focus");
	        bufferedOutputStream.flush();
	        bufferedOutputStream.close();
	        //3.创建输入流,读取Java基本类型数据
	        DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
	        System.out.println(dataInputStream.readInt());
	        System.out.println(dataInputStream.readDouble());
	        System.out.println(dataInputStream.readBoolean());
	        System.out.println(dataInputStream.readUTF());
	        dataInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

DataOutputStream和DataInputStream是相互配合使用,我们可以给文件中写入Java基本数据类型,然后再读取出来,也就是允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型,但是在读取时要保证顺序一致性,否则会导致java.io.EOFException。一个int是32位,4个字节,我们是用字节流的形式保存的

PushBackInputStream简介

PushBackInputStream回退流,可以把读取的数据放回去再读取一遍。
public void unread(int b) throws IOException是回退流中的回退方法
在这里插入图片描述
比如上面的文本,我想把.重新读一遍

public class PushBackInputStreamTest {
    public static void main(String[] args) throws Exception{
        //1.得到数据文件
        String filePath = "E:\\ExampleTest\\TestText.txt";
        File file = new File(filePath);
        //2.创建缓冲输入流
        PushbackInputStream inputStream = new PushbackInputStream(new FileInputStream(file));
        int temp = 0;
        while ((temp = inputStream.read()) != -1) {
            if (temp == '.') {
                inputStream.unread((char)temp);
                System.out.println("退回" + (char)temp);
                temp = inputStream.read();
                System.out.println((char)temp);
            }else {
                System.out.println((char)temp);
            }
        }
        inputStream.close();
    }
}

结果如下图所示:
在这里插入图片描述

ObjectInputStream&ObjectOutputStream简介

ObjectInputStream可以从输入流中读取Java对象,它和DataInputStream的区别是DataInputStream只能读取基本类型,而ObjectInutStream可以读取基本类型和对象,所读取的对象必须实例化。

实例化类Man,我们先将它的对象写入文件中,然后读取出来

public class Man implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

    public Man(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

public class ObjectInputStreamTest {

    public static void main(String[] args) throws Exception{
        //1.得到数据文件
        String filePath = "E:\\ExampleTest\\TestText.txt";
        File file = new File(filePath);
        file.createNewFile();
        //2.创建输出流,写入Java类
        Man man = new Man("LiYunLong", 39);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
        objectOutputStream.writeObject(man);
        objectOutputStream.writeUTF("End");
        objectOutputStream.close();
        //3.创建输入流,读取java类
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
        Man secondMan = (Man) objectInputStream.readObject();
        System.out.println(secondMan.getName());
        System.out.println(secondMan.getAge());
        System.out.println(objectInputStream.readUTF());
        objectInputStream.close();
    }
}

结果:
在这里插入图片描述

PipedInputStream&PipedOutputStream简介

PipedInputStream可以用于两线程之间通信,在线程之间发送消息
public void connect(PipedOutputStream src)public void connect(PipedInputStream snk)分别是PipedInputStreamPipedOutputStream的方法,两者的实质没有区别,就是将两个线程之间的

public class PipedInputStreamTest {

    public static void main(String[] args) throws IOException {
        SenderThread senderThread = new SenderThread();
        ReceiverThread receiverThread = new ReceiverThread();
        //将两个线程连接起来
        receiverThread.getPipedInputStream().connect(senderThread.getPipedOutputStream());
        //与上面代码实质一样
        //senderThread.getPipedOutputStream().connect(receiverThread.getPipedInputStream());
        senderThread.run();
        receiverThread.run();
    }
}
//发送线程
public class SenderThread extends Thread {

    private PipedOutputStream pipedOutputStream = new PipedOutputStream();

    public PipedOutputStream getPipedOutputStream() {
        return pipedOutputStream;
    }

    @Override
    public void run() {
        try {
            //发送一条消息
            pipedOutputStream.write("A message for you".getBytes());
            pipedOutputStream.flush();
            pipedOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//接受线程
public class ReceiverThread extends Thread{

    private PipedInputStream pipedInputStream = new PipedInputStream();

    public PipedInputStream getPipedInputStream() {
        return pipedInputStream;
    }
    
    @Override
    public void run() {
        byte[] bytes = new byte[1024];
        try {
            //接受一条消息
            pipedInputStream.read(bytes);
            pipedInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(new String(bytes));
    }
}
SequenceInputStream简介

合并流,可以多个流合并成一个流,从而操作起来更加方便。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾;接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止

StringBufferInputStream简介

StringBufferInputStream这个类已经打上了@Deprecated(废弃)注解,所以不应该用这个类写代码,StringBufferInputStream类的本意是把字符串转换为字节流,然后进行读操作,但是这个类实现中仅仅使用了字符编码的低8位,不能把字符串中的所有字符(比如中文字符)正确转换为字节,因此这个类已经被废弃,取而代之的是StringReader类

ByteArrayInputStream简介

字节数组输入流在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区中

public class ByteArrayInputStreamTest {

    public static void main(String[] args) throws Exception{
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("Hello".getBytes());
        byte[] bytes = new byte[1024];
        byteArrayInputStream.read(bytes);
        System.out.println(new String(bytes));
        byteArrayInputStream.close();
    }
}

OutputStream常用的类&方法

常用类含义
OutputStreamOutputStream抽象类是表示字节输出流的所有类的超类,它以字节为单位将数据写入数据源
FileOutputStream以字节为单位将数据写入到文件
FilterOutputStream装饰其它输出流,并为它们提供额外的功能
BufferedOutputStrean装饰其它输出流,给输出流提供缓冲功能,提高写入效率
DataOutputStrean装饰其它输出流,它允许应用程序以与机器无关方式向底层写入Java基本数据类型
PrintStream装饰其它输出流,使它们能够方便地打印各种数据值表示形式
ObjectOutputStream将对象信息写入到输出流
PipedOutputStream与其它线程共用的管道中写入数据
ByteArrayOutputStream在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中
常用方法含义
public abstract void write(int b) throws IOExecption该方法用于将指定的字节写入到输出流
public int write(byte[] b) throws IOExecption该该方法用于将b.length个字节从指定的byte数组写入到输出流
public int write(byte[] b,int off,int len) throws IOExecption该方法用于将len个字节的数据,并从数组b的off位置开始写入到输出流
public void close() throws IOExecption关闭此输出流,并释放与此输出流相关联的所有系统资源
FileOutputStream简介

FileOutputStream是向文件中写入数据,所以我们给txt文件中写一些数据,然后看一下

public class FileOutputStreamTest {

    public static void main(String[] args) throws IOException {
        //1.创建写入文件
        File file = new File("E:\\ExampleTest\\TestText.txt");
        file.createNewFile();
        //2.创建输出流,然后写入数据
        OutputStream outputStream = new FileOutputStream(file);
        outputStream.write("Hello World".getBytes());
        outputStream.flush();
        outputStream.close();
    }
}

结果:
在这里插入图片描述

FilterOutputStream简介

FilterOutputStream类似于FilterInputStream,是一个抽象类,它的子类BufferedOutputStream,DataOutputStream,PrintStream可以修饰其它输出类,添加一些额外的功能

BufferedOutputStream简介

BufferedOutputStream类似于BufferInputStream,是个带缓冲区的输出流,可以用来修饰其它输出流,从而提高写入性能

public class BufferedOutputStreamTest {

    public static void main(String[] args) throws Exception {
        //1.创建准备写入的文件
        File file = new File("E:\\ExampleTest\\TestText.txt");
        file.createNewFile();
        //2.创建输出流,写入数据
        OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
        outputStream.write("BufferedOutputStreamTest".getBytes());
        outputStream.flush();
        outputStream.close();
    }
}
PrintStream简介

PrintStream是FilterOutputStram的子类,可以用来修饰其它输出流。PrintStream还提供了自动flush功能,往PrintStream写入的数据会立刻调用flush()函数

public class PrintStreamTest {

    public static void main(String[] args) throws Exception{
        //1.创建准备写入的文件
        File file = new File("E:\\ExampleTest\\TestText.txt");
        file.createNewFile();
        //2.创建输出流,写入数据
        PrintStream printStream = new PrintStream(new FileOutputStream(file));
        printStream.println("Hello World");
        printStream.println("你好世界");
        printStream.println(true);
        printStream.close();
    }
}

结果:
在这里插入图片描述
不管是什么数据类型,PrintStream都会将其转变为字符串,然后输出。我们经常使用的System.out.println();中的out就是一个PrintStream对象

ByteArrayOutputStream简介

在创建ByteArrayOutputStream实例时,会在程序内部创建一个byte型数组的缓冲区,缓冲区会随着数据的不断写入而自动增长,可以使用toByteArray()或者toString()获取数据,也可以使用ByteArrayInputStream来获取

public class ByteArrayOutputStreamTest {

    public static void main(String[] args) throws Exception{
        //1.创建准备写入的文件
        File file = new File("E:\\ExampleTest\\TestText.txt");
        file.createNewFile();
        //2.创建输出流,写入数据
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write("ok".getBytes());
        byteArrayOutputStream.write(1);
        //3.使用输入流读取数据
        byte[] bytes = byteArrayOutputStream.toByteArray();
        ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(bytes);
        int length = 0;
        while ((length = arrayInputStream.read()) != -1) {
            System.out.println(length);
        }
        byteArrayOutputStream.close();
        arrayInputStream.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值