大白糖奶兔的Blog
大白糖奶兔的Blog
Java学习-Day11文件和流

流的分类

字节流

字节输入流类是InputStream类及其子类

抽象字节流 InputStream:程序可从中连续读取一系列字节的对象称为字节输入流

字节输出流类是OutputStream类及其子类

字符流

字符输入流类是Reader类及其子类

字符输入流类是Writer类及其子类

抽象字节流

InputStream

程序可从中连续读取一系列字节的对象称为字节输入流

InputStream类是所有字节输入流的父类,抽象类,提供了读取字节等方法

三个基本的读方法

  • abstract int read() throws IOException
  • int read(byte[] b) thorws IOException
  • int read(byte[] b,int off,int len) thorws IOException
  • void close():关闭输入流,释放相关资源

OutputStream

程序可以向其中连续写入一系列字节的对象称为字节输出流

OutputStream是所有字节输出流的父类,是抽象类,提供了写入字节的方法

三个基本写方法

  • abstract void write(int b) throws IOException
  • void write(byte[] b)thorws IOException
  • void write(byte[] b,int off,int len) throws IOException
  • void close() throws IOException

b表示包含内容的字符数组,off表示从哪个字节开始,len表示读多长

总之,InputStream的子类的方法是从外部读取数据,存到字节数组当中

而OutputStream的子类的方法是把数据写入文件、屏幕等,

https://yczbest.cn/wp-content/uploads/2020/07/image-1-1024x570.png
字节输出流类及其子类的层次结构

文件字节流

读取文件数据的文件输入流的构造方法

  • FileInputStream(String name) thorws FileNotFoundException
  • FileInputStream(File file) throws FileNotFoundException

将数据写入文件的文件输出流的构造方法

  • FileOutputStream(String name) throws FileNotFoundException
  • FileOutputStream(File f) throws FileNotFoundException
  • FileOutPutStream(String name,boolean append) throws FileNotFoundException

第三种方法用于文件已经存在,是否需要追加内容的情况下,false覆盖(默认),true追加

程序一

package 第八章文件和流;
import java.io.*;
public class 字节流 {
    public static void main(String[] args) {
        int data;//一个整形数据32位,4字节
        System.out.println("请输入:");
        try{
//            System.in是一个InputStream字节输入流,所以包含read()方法
            //read()方法读取方法,返回读取到的字节数给data
//            当输入的数据不为-1时循环读入输入的数据
            while((data = System.in.read()) != -1 ){
//                System.out是标准输出流,所以包含write方法
                System.out.write(data);//输出字符
                System.out.print(data);//输出字节,也就是对应的ASCII码
            }
        }catch(Exception e){}
    }
}

这个程序中要注意的是System.out.write()这个方法,它和System.out.print()

是有区别的,write()是输出字符,将data中的数据转换成字符进行输出

print()或者println()是将data中的数据以字节的形式输出

而什么是字符,什么是字节?

1个字节等于8位,每位有0/1两种状态也就是说一个字节可以表示256个状态,也就是说,字节输出,指的就是输出ASCII码

一般来说,英文状态下一个字母或数字(称之为字符)占用一个字节,一个汉字用两个字节表示。在不同的编码方式下一个字符占的字节数不太一样。 

本程序中输入a,write()会输出97,print会输出a,因为输入的时候是用输入字节流输入的,所以输出存储的data内容是字节形式的数据,也就是ASCII码形式

程序二

package 第八章文件和流;
import java.io.*;
public class 文件输入输出流 {
    public static void main(String[] args) {
        try{
            //文件写入操作
            //创建文件输出流对象fos
            FileOutputStream fos = new FileOutputStream("./test.txt");
            fos.write("文件写入测试".getBytes());//write()方法接收的参数是字节数组(public void write(byte b[]))
            // 在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组
            fos.close();//关闭末尾流

            //文件读取操作
            //创建文件输入流对象fis
            FileInputStream fis = new FileInputStream("./test.txt");
            byte[] buf = new byte[100];//read的形参需要接收字符数组,所提提前创建好
            int len = fis.read(buf);//字节数租存储从文件输入流读取到的内容,并返回内容长度len
            //匿名String对象的构造函数,形参分别为字节数组,开始读取的位置,读取长度
            System.out.println(new String(buf,0,len));
            fis.close();
        }catch (Exception e){e.printStackTrace();}
    }
}

Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组

在写入文件操作中,因为write的形参需要字节数组,所以利用了String.getBytes()方法,小驼峰命名方法

缓冲字节流

缓冲字节流是一个过滤流,创建BufferedInputStream或者BufferedOutputStream对象的时候,形参要接收一个已经存在的、创建好的输入流对象或输出流对象(例如fis,fos)

构造方法

  • BufferedInputStream(InputStream in)
  • BufferedInputStream(InputStream in,int size)
  • BufferedOutputStream(OutputStream out)
  • BufferedOutputStream(OutputStream out,int size)

void flush() throws IOException//刷新缓冲区立即输出并清空缓冲区,空实现

package 第八章文件和流;
import java.io.*;
public class 缓冲区流 {
    public static void main(String[] args) {
        try{
//          创建文件输出流对象fos
            FileOutputStream fos = new FileOutputStream("./test.txt");
            //添加缓冲流
            BufferedOutputStream bos = new BufferedOutputStream(fos);
//          先把内容写进缓冲区,如果缓冲区满了再写入文件
            bos.write("测试缓冲区".getBytes());
//            bos.flush();//第一种方法:手动刷新缓冲区、立即将缓冲区内容输出到文件,并清空缓冲区
            fos.write("www.baidu.com".getBytes());//将字符串写入文件
            bos.close();//第二种方法:关闭末尾流的时候会刷新缓冲区,将缓冲区内容写入文件
            //缓冲功能写

//            读取文件内容
            FileInputStream fis = new FileInputStream("./test.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
            byte[] buf = new byte[100];//read的形参需要接收字符数组,所提提前创建
            int len = bis.read(buf);
            //匿名String对象的构造函数,形参分别为字节数组,开始读取的位置,读取长度
            System.out.print(new String(buf, 0, len));
            bis.close();//只关闭末尾流
        }catch (Exception e){}
    }
}

数据字节流

提供读写基本数据类型的方法,过滤流

构造方法

  • public DataInputStream(InputStream in)
  • public dataOutputStream(OutputStream out)

提供各种数据类型的输入方法

  • public final byte readByte() throws IOException
  • public final short readShort() throws IOException
  • public final int readInt() throws IOException
  • public final long readLong() throws IOException
  • public final char readChar() throws IOException
  • public final boolean readBoolean() throws IOException
  • public final float readFloat() throws IOException
  • public final double readDouble() throws IOException

提供各种数据类型的输出方法

  • public final void writeByte(int v) throws IOException
  • public final void writeShort(int v) throws IOException
  • public final void writeint(int v) throws IOException
  • public final void writeChar(int v) throws IOException
  • public final void writeLong(long v) throws IOException
  • public final void writeBoolean(boolean v) throws IOException
  • public final void writeFloat(float v) throws IOException
  • public final void writeDouble(double v) throws IOException
  • public final void writeChars(String s) throws IOException

Demo

package 第八章文件和流;
import java.io.*;

public class 数据操作 {
    public static void main(String[] args) {
        try{
            FileOutputStream fos = new FileOutputStream("test.txt");
            //添加缓冲流
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            //字节输入输出流,基本数据类型的输入输出(过滤流)
            DataOutputStream dos = new DataOutputStream(bos);
            byte b = 3;
            int i = 12;
            char c = 'e';
            float f = 1.5f;
            dos.writeByte(b);
            dos.writeInt(i);
            dos.writeChar(c);
            dos.writeFloat(f);
            dos.close();//末端流关闭,刷新缓冲区
            
//          读取数据
            FileInputStream fis = new FileInputStream("test.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
            DataInputStream dis = new DataInputStream(bis);
            //读的顺序要与写的顺序一致
            System.out.println(dis.readByte());
            System.out.println(dis.readInt());
            System.out.println(dis.readChar());
            System.out.println(dis.readFloat());
            dis.close();
        }catch (Exception e){}
    }
}

对象字节流

对字节流的读写操作以对象为单位,每次读取或写入一个对象

把一个对象的表示转换成一个字节流的过程称为对象序列化

从字节流中重建对象的过程称为去序列化(或者叫反序列化

java.io.Serializable序列化接口,没有任何方法,为标记接口

构造方法

  • public ObjectOutputStream(OutputStream out) thorws Exception
  • public ObjectInputStream(InputStream in) throws Exception

写入、读取方法

写入方法

  • public final void writeObject(Object obj) throws IOException

读取方法

  • public final Object readObject() thorws IOException,ClassNotFoundException
package 第八章文件和流;

import java.io.*;

public class 对象字节流 {
    public static void main(String[] args) {
        try{
            Employee e1 = new Employee("小智1",20,9000.00d);
            Employee e2 = new Employee("小智2",20,9000.00d);
            Employee e3 = new Employee("小智3",20,9000.00d);
            FileOutputStream fos = new FileOutputStream("./employee.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(e1);//对象序列化
            oos.writeObject(e2);
            oos.writeObject(e3);
            oos.close();//末端流关闭

            //读取文件
            FileInputStream fis = new FileInputStream("employee.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Employee e;
            for (int i = 0; i < 3; i++) {
                e =(Employee)ois.readObject();//反序列化
                System.out.println("姓名:" + e.name);
                System.out.println("年龄:" + e.age);
                System.out.println("薪水:" + e.salary);
                System.out.println("------------------------");
            }
            ois.close();
        }catch(Exception e){}
    }
}
class Employee implements Serializable {
//    序列化标记接口
    String name;
    int age;
    double salary;
    public Employee(String name,int age,double salary){
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
}

管道字节流

管道流提供在对象之间传输数据的基本手段

既可以是字节流也可以是字符流

构造函数

  • public PipedInputStream(PipedOutputStream src) throws IOException
  • public PipedOutputStream(PipedInputStream src) throws IOException

写入、读取方法

InputStream的方法

  • public void connect(PipedOutputStream src) throws IOException

OutputStream的方法

  • public void connect(PipedInputStream src) throws IOException

两者只能用其中一个,不可同时使用

Demo

package 第八章文件和流;

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

public class 管道流 {
    public static void main(String[] args) {
        try{
            PipedOutputStream pos = new PipedOutputStream();
            PipedInputStream pis = new PipedInputStream();
            pos.connect(pis);//链接输入输出管道
            new Producer(pos).start();
            new Consumer(pis).start();
        }catch(Exception e){}
    }
}

class Producer extends Thread {
    private PipedOutputStream pos;//管道输出流写入文件
    public Producer(PipedOutputStream pos){
        this.pos = pos;//构造函数
    }
    public void run() {
        try{
            pos.write("生产者生产成功".getBytes());
            pos.close();
        }catch(Exception e){}
    }
}
class Consumer extends Thread{
    private PipedInputStream pis;
    public Consumer(PipedInputStream pis){
        this.pis = pis;
    }
    public void run() {
        try{
            byte[] buff = new byte[100];
            int len = pis.read(buff);
            System.out.println(new String(buff,0,len));
            pis.close();
        }catch(Exception e){}
    }
}

字符流

发表评论

textsms
account_circle
email

大白糖奶兔的Blog

Java学习-Day11文件和流
流的分类 字节流 字节输入流类是InputStream类及其子类 抽象字节流 InputStream:程序可从中连续读取一系列字节的对象称为字节输入流 字节输出流类是OutputStream类及其子…
扫描二维码继续阅读
2020-06-07
Title - Artist
0:00