java IO流详细总结(一、字节输入输出流)

简介: java IO流详细总结(一、字节输入输出流)

一、什么是IO流:

将数据从内存传输到外部存储设备的通道,管道。

IO流的分类:

1.按方向划分:<以JVM为参照物>

输入流:将<外部存储设备>中的数据读入到<内存>中。

输出流:将<内存>中的数据写入到<外部存储设备>中。


2.按单位划分:

字节流:以字节(8bit)为单位,能够传输所有类型的文件。

字符流:以字符为单位,一次可能读多个字节。.只能传输文本文件(能够被记事本打开.java/.txt/.html,并且不改变内容的文件)


只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。


3.按功能划分:

节点流:具有基本的读写功能

过滤流:在节点流的基础上,增加了新的功能


二、IO流常用类库:

三、java IO流对象

1.字节输入(输出)流InputStream/OutputStream中输入字节流的继承图可见上图,可以看出:


InputStream/OutputStream 是所有的输入(输出)字节流的父类,它是一个抽象类。

常用子类FileOutputStream:文件字节输出流

常用方法为:(返回值类型都为void)

      void write(int b):向外部存储设备中写入数据
      void write(byte[] b) :向指定文件中写入 数组长度个 字节
      void write(byte[] b, int off, int len) :向指定文件中写入数组中指定的字节
            b:数组  off:开始下标   len:个数
      void close(): 关闭资源

FileInputStream:文件字节输入流

常用方法: (返回值类型都为int)

      int read():从输入流中读取一个字节,返回值表示字符的整数表现形式,若没有字符  则返回-1
      int read(byte[] b):从输入流中读取多个字节,返回值表示读取的有效字节个数
      int read(byte[] b, int off, int len) :
        b:数组  off:存储到数组的指定下标  len:存储个数

BufferedOutputStream/BufferedInputStream、DataOutputStream/DataInputStream、ObjectOuputStream/ObjectInputStream都是字节过滤流。

其中,BufferedOutputStream/BufferedInputStream 字节输入输出过滤缓冲流,可以提高IO的效率,减少磁盘的访问次数。数据存储在数据缓冲区中,需要使用flush方法 清空缓冲区。也可以直接使用close方法。

例如:

package test;
import java.io.FileOutputStream;
import java.io.IOException;
/**
 * @author 超伟
 * @date 2019年5月16日  
 * @博客: https://blog.csdn.net/MacWx  
 */
public class testOutput {
  public static void main(String[] args) throws IOException {
    //创建文件输出流
    FileOutputStream fo = new FileOutputStream("file/test.txt");
    //往文件中写入一个char数据,
    fo.write(65);
    //创建一个byte类型数组
    byte[] b = new byte[]{66,67,68,69};
    //将此数组写入到文件中
    //fo.write(b);
    //将此数组中的下标为1的开始,的后两个字符写入到文件中
    fo.write(b, 0, 4);
    //关闭输出流
    fo.close();
    //FileOutputStream的两参构造方法,第一个参数传的是文件名,
    //第二个参数如果是true,则使文件添加,否则覆盖!
    FileOutputStream file = new FileOutputStream("file/test.txt",true);
    String s  = "今天星期五";
    byte[] cs = s.getBytes();
    //将字符串数组添加写入文件中
    file.write(cs);
    //关闭流
    file.close();
  }
}

上面程序是将一个自定义的字符或者字符串通过FileOutputStream写入到文件中去的,那么怎么从一个文件中把数据读取到java虚拟机JVM并通过控制台打印出来呢?

package test;
import java.io.FileInputStream;
import java.io.IOException;
/**
 * @author 超伟
 * @date 2019年5月16日  
 * @博客: https://blog.csdn.net/MacWx  
 */
public class testInput {
  public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    //创建文件读入流
    FileInputStream f = new FileInputStream("file/test.txt");
    //返回读入文件的整数表现形式
    //int read = f.read();
    byte b[] = new byte[3];
    //测试通过数组读取文件中的信息
    //f.read(b,0,2);
    //再通过死循环遍历读入的文件所有内容,
    //如果到最后一个字节为空即等于-1的时候break跳出循环
    while(true){
      int reads = f.read();
      if (reads== -1) {
        break;//跳出死循环
      }
      //输出读取到的字节,再强转回char类型
      System.out.print((char)reads);
    }
    //关闭资源
    f.close();
  }
}

DataOutputStream/DataInputStream 主要用来操作基本数据类型,和字符串的输入输出。

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestDataOuputStream {
  public static void main(String[] args) throws IOException {
    //创建节点流
    FileOutputStream fileOutputStream = new FileOutputStream("file/f.txt");
    //创建过滤流
    DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
    //写操作,往文件中写入浮点数12.5;
    dataOutputStream.writeDouble(12.5);
    //关闭资源
    dataOutputStream.close();
  }
}

ObjectOuputStream/ObjectInputStream 对象输入输出过滤流,主要增强缓冲区的功能,同时增强了操作基本数据类型和字符串类型的能力

可以操作对象

writeObject(Object obj):向外部存储设备写入对象数据类型

Object readObject():从外部存储设备读入对象,返回值为读入的对象


对象放在流上进行传输的过程称为对象序列化。


要求:自定义的类必须实现Serializable接口


需要注意:

i.被transient修饰的属性,不参与序列化

ii. java.io.EOFException 文件到达尾部

文件中只有一个对象,连续读取两次 就会报此异常

iii.如果参与序列化对象有对象类型的属性,则这个属性类型也必须实现Serializable

iv.当序列化对象为集合时,它的对象元素类型,也必须实现Serializable接口

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class TestObjectOutputStream {
  public static void main(String[] args) throws IOException {
    //创建节点流
    FileOutputStream fileOutputStream = new FileOutputStream("file/d.txt");
    //创建包装、过滤流
    ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream);
    //执行写操作
    //写入一个对象
    Student s = new Student("macw",22);
    oos.writeObject(s);
    //关闭资源
    oos.close();
  }
}
class Student implements Serializable{  //对学生对象 实现了序列化
  private static final long serialVersionUID = 1L;
  private String name;
  private transient int age;   //被transient修饰的属性,不参与序列化
  private Address add = new Address();
  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 Student() {
    super();
  }
  public Student(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  }
  @Override
  public String toString() {
    return "Student [name=" + name + ", age=" + age + "]";
  }
}
class Address implements Serializable{}

谈一下使用IO流进行文件复制的操作:

用FileInputStream 和 FileOutputStream 实现文件的复制。

其基本实现流程为先使用FileInputStream.read()方法读取到文件中的数据,再将读取到JVM中的数据通过FileOutputStream.write()方法写入到想要复制的文件中。

还可以实现字节包装类(过滤流也加包装类,同一个意思)来增强缓冲区的功能,提高IO的效率,减少磁盘的访问次数。

例如:

使用IO流将图片“gril.jpg”复制到“file”文件下

package work;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
 * @author 超伟
 * @date 2019年5月16日  
 * @博客: https://blog.csdn.net/MacWx  
 */
public class t11 {
  public static void main(String[] args) throws IOException {
    //创建文件字节输入流对象,
    FileInputStream fileInputStream = new FileInputStream("E:\\java\\练习\\gril.jpg");
    //创建文件字节输出流对象,
    FileOutputStream fileOutputStream = new FileOutputStream("file/gril.jpg");
    //分别对输入输出流对象通过过滤流进行包装,提高IO的效率
    BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
    //记录程序运行开始复制时的当前时间,目的是为了测试本次复制效率如何
    long start = System.currentTimeMillis();
    //通过死循环遍历原文件中的每一个字节,遍历到最后字节为空即等于-1时跳出死循环
    while (true) {
      int read = bufferedInputStream.read();
      if (read == -1) {
        break;
      }
      //将读取到的每一个字节一次写入到复制的新文件中
      bufferedOutputStream.write(read);
    }
    //关闭所有流资源
    bufferedInputStream.close();
    bufferedOutputStream.close();
    long end = System.currentTimeMillis();
    //通过程序结束时的当前时间减去开始时间查看复制效率
    System.out.println(end - start);
  }
}

这样就可以完成文件的简单复制操作了!

由于篇幅限制下一篇介绍IO流的字符输入输出流…

目录
相关文章
|
1月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
67 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
1月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
35 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
76 1
|
30天前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
46 0
|
2月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
35 0
|
2月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
3月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
46 2
|
3月前
|
NoSQL Java Redis
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常