Java基本输入输出字节流实现类的使用

1. 基本字节输入输出流实现类

Java基本字节流相关实现类

2. 输入输出字节流的分类

按方向:
① 输入流:将[存储设备]中的内容输入到[内存]中;
② 输出流:将[内存]中的内容输出到[存储设备]中。

相对于程序操作的内存,进入内存为输入,从内存出去为输出。

按单位:
① 字节流:以字节为单位,可以读写所有数据;
② 字符流:以字符为单位,只能读写文本数据。
按功能:
① 节点流:具有实际传输数据的读写功能;
② 过滤流:在节点流的基础之上增强功能。

3. 抽象父类:InputStream & OutputStream

InputStream字节输入流:

public abstract class InputStream
    extends Object
    implements Closeable

这个抽象类是表示输入字节流的所有类的超类。需要定义InputStream子类的应用InputStream必须始终提供一种返回输入的下一个字节的方法。

abstract int read()
从输入流读取数据的下一个字节。
int read(byte[] b)
从输入流读取一些字节数,并将它们存储到缓冲区 b 。
int read(byte[] b, int off, int len)
从输入流读取最多 len字节的数据到一个字节数组。

OutputStream字节输出流:

public abstract class OutputStream
    extends Object
    implements Closeable, Flushable

这个抽象类是表示字节输出流的所有类的超类。 输出流接收输出字节并将其发送到某个接收器。需要定义OutputStream子类的应用OutputStream必须至少提供一个写入一个字节输出的方法。

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

3.1 实现类:字节节点流 FileOutputStream & FileInputStream

  • FileOutputStream类(字节节点输出流):
public class FileOutputStream
    extends OutputStream

核心方法:

void write(int b)
将指定的字节写入此文件输出流。
void write(byte[] b)
将 b.length个字节从指定的字节数组写入此文件输出流。
void write(byte[] b, int off, int len)
将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。

构造方法:

FileOutputStream(File file)
创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(File file, boolean append)
创建文件输出流以写入由指定的 File对象表示的文件,append==true追加,不覆盖。
FileOutputStream(FileDescriptor fdObj)
创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
FileOutputStream(String name)
创建文件输出流以指定的名称写入文件。
FileOutputStream(String name, boolean append)
创建文件输出流以指定的名称写入文件。

示例代码:

public class TestFileOutputStream {
      public static void main(String[] args) throws IOException {
            // 1.输出字节流 OutputStream
            // 2.输出字节节点流,具有实际传输数据的功能,boolean append ==  true不覆盖原文件内容,追加写入
            // 3.路径正确,文件不存在,会自动创建文件
            // 4.使用相对路径,相对于当前项目的路径,寻找路径和文件
            FileOutputStream fos = new  FileOutputStream(".\\files\\target.txt", true);
            
            try {
                  String s = "你";
                  fos.write(s.getBytes()); // 写入中文
                  
                  fos.write(65); // 写入字符
                  fos.write(66);
                  fos.write(67);
                  fos.write('D');
                  byte[] bs = new byte[] {65, 66, 67, 68, 69, 'Z'}; //  写入字符数组
                  fos.write(bs);
                  System.out.println("OK");
            } catch (IOException e) {
                  e.getStackTrace();
            } finally {
                  fos.close();
            }
      }
}
  • FileInputStream类(字节节点输入流):
public class FileInputStream
    extends InputStream

核心方法:

int read()
从该输入流读取一个字节的数据。
int read(byte[] b)
从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件尾部,返回-1
int read(byte[] b, int off, int len)
从该输入流读取最多 len字节的数据为字节数组。

构造方法:

FileInputStream(File file)
通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(FileDescriptor fdObj)
创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
FileInputStream(String name)
通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

示例代码:

public class TestFileInputStream {
      public static void main(String[] args) throws IOException {
            FileInputStream fis = new  FileInputStream(".\\files\\target.txt");
            try {
                  // 逐个字节读入
//                while (true) {
//                      int n = fis.read();
//                      if (n < 0) { // -1, 文件结尾EOF
//                            break;
//                      }
//                      System.out.println((char)n);
//                }
                  
                  // 按照数组读入
                  byte[] bs = new byte[4];
                  while(true) {
                        int count = fis.read(bs); // count:每次读取到的有效字节个数
                        if (count < 0) { // -1, 文件结尾EOF
                              break;
                        }
                        // 读多少个,输出多少个
                        for (int i = 0; i < count; i++) {
                              System.out.print((char)bs[i]);
                        }
                        System.out.println();
                  }
                  
                  //read(bs, off, len); // 读入bs数组中,从off下标开始,每次读入len
                  
            } catch (Exception e) {
                  e.printStackTrace();
            } finally {
                  fis.close();
            }
      }
}

输入输出综合使用场景:

public class TestFileIOcopy {
      public static void main(String[] args) throws IOException {
            // 拷贝一张图片
            FileInputStream fis = new  FileInputStream("C:\\Users\\Administrator\\Desktop\\test.jpg");
            FileOutputStream fos = new  FileOutputStream("files\\new.jpg");
            int data = 0;
            
            try {
                  // 无参的read()返回的是数据
                  while ((data = fis.read()) >= 0) {
                        System.out.println(data);
                        fos.write(data);
                  }
            } finally {
                  fis.close();
                  fos.close();
            }
      }
}

3.2 实现类:字节过滤流(缓冲流)BufferedOutputStream & BufferedInputStream

特点:

  • 提高IO效率,减少访问磁盘次数;
  • 数据存储在缓冲区中,flush是讲缓存区的内容写入文件中,也可以直接close;
public class BufferedOutputStream
    extends FilterOutputStream

public class BufferedInputStream
    extends FilterInputStream

示例演示:

public class TestBufferredOutput {
      public static void main(String[] args) throws IOException {
            // 输出节点流
            FileOutputStream fos = new  FileOutputStream("files\\buffer.txt");
            // 增强节点流:有参构造需要一个字节输出节点流
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            try {
                  // 过滤流的write方法,是先写入到缓冲区数组里
                  bos.write('A');
                  bos.write('B');
                  bos.write('C');
                  // 刷新缓冲区:将缓冲区的数据,或一次性写入文件中,并清空当前缓冲区
                  bos.flush();
                  bos.write('E');
                  // 每次均需刷新缓冲区
                  //bos.flush();
            } catch (Exception e) {
                  e.printStackTrace();
            } finally {
                  // .close() 级联的执行了flush();释放了资源的同时,将缓冲器的数据一次性写入到文件中
                  bos.close();
                  System.out.println("写入OK");
            }
            
            // 输入字节流 - 普通的即可
            FileInputStream fis = new  FileInputStream("files\\buffer.txt");
            //BufferedInputStream bis = new BufferedInputStream(fis);
            byte[] b = new byte[100];
            fis.read(b);
            for (int i = 0; i < b.length; i++) {
                  System.out.println((char)b[i]);
            }
            
            fis.close();
      }
}

3.3 实现类:字节过滤流(对象流)ObjectOutputStream & ObjectInputStream

public class ObjectOutputStream
    extends OutputStream
    implements ObjectOutput, ObjectStreamConstants

public class ObjectInputStream
    extends InputStream
    implements ObjectInput, ObjectStreamConstants

特点:

  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串功能
  • 增强了读写对象的功能:
    1. Object readObject() // 从流中读取一个对象
    2. void writeObject(Object obj) // 向流中写入一个对象
  • 对象序列化:
    使用流传输对象的过程称为序列化、反序列化。
  1. 必须实现Serializable接口
  2. 对象自身和类中属性都必须序列化(即实现Serializable这个空接口即可,基本数据类型数组可不序列化,引用数据类型必须序列化);
  3. transient 关键字修饰为临时属性,不参与序列化;
  4. 对象的默认序列化机制写入对象的类、类签名和所有非瞬态和非静态字段的值,因此属性不能使用static修饰,否则取的都是最后一次的值(static属于类本身,会影响序列化)。
  5. 序列化对象流读取到文件尾,会抛出 EOFException 异常 - 捕获后停止读取文件
public class TestObjectStream {
      public static void main(String[] args) throws IOException,  ClassNotFoundException {
            // 写
            OutputStream os = new  FileOutputStream("files\\target.txt");
            ObjectOutputStream oos = new ObjectOutputStream(os);
            Student stu = new Student("小明", 12, "男", 100D);
            Student stu1 = new Student("小黑", 13, "男", 60D);
            oos.writeObject(stu); // NotSerializableException: 类实现Serializable接口即可
            oos.writeObject(stu1);
            oos.flush();
            oos.close();
            // 读
            InputStream is = new FileInputStream("files\\target.txt");
            ObjectInputStream ois = new ObjectInputStream(is);
            while (true) {
                  try {
                  Object obj = ois.readObject();
                  System.out.println(obj);
                  } catch (EOFException e) {
                        // 到达文件尾,抛出EOFException文件尾异常
                        break;
                  }
            }
            ois.close();
      }
}
// 对象需要实现序列化
// 属性也需要实现序列化
class Student implements Serializable {
      private static final long serialVersionUID = 1L;
      /*static*/String name; // static为类所有,会影响该属性值变为一个相同的值
      Integer age;
      String sex;
      transient Double score; // transient修饰的属性不参与序列化,均为null
      public Student() {
            super();
      }
      public Student(String name, Integer age, String sex, Double  score) {
            super();
            this.name = name;
            this.age = age;
            this.sex = sex;
            this.score = score;
      }
      @Override
      public String toString() {
            return "Student [name=" + name + ", age=" + age + ", sex="  + sex + ", score=" + score + "]";
      }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容