java IO --- IO流

简介: java IO --- IO流

IO其实意味着:数据不停地搬入搬出缓冲区而已(使用了缓冲区)。


什么是Java序列化和反序列化,如何实现?


  • 把Java对象转换为字节序列的过程称为对象的序列化,也就是将对象写入到IO流中。序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
    ps:要对一个对象序列化,这个对象就需要实现Serializable接口,如果这个对象中有一个变量是另一个对象的引用,则引用的对象也要实现Serializable接口,这个过程是递归的。Serializable接口中没有定义任何方法,只是作为一个标记来指示实现该接口的类可以进行序列化。


实现序列化:


  • 步骤一:创建一个ObjectOutputStream输出流;
  • 步骤二:调用ObjectOutputStream对象的 writeObject 方法输出可序列化对象。


image.png

序列化只能保存对象的非静态成员变量,而不能保存任何成员方法和静态成员变量,并且保存的只是变量的值,变量的修饰符对序列化没有影响。


有一些对象类不具有可持久化性,因为其数据的特性决定了它会经常变化,其状态只是瞬时的,这样的对象是无法保存去状态的,如Thread对象或流对象。对于这样的成员变量,必须用 transient 关键字标明,否则编译器将报错。任何用 transient 关键字标明的成员变量,都不会被序列化。


另外,序列化可能涉及将对象存放到磁盘上或在网络上发送数据,这时会产生安全问题。对于一些需要保密的数据(如用户密码等),不应保存在永久介质中,为了保证安全,应在这些变量前加上 transient 关键字。


反序列化就是从 IO 流中恢复对象。反序列化实现:


  • 步骤一:创建 ObjectInputStream 输入流
  • 步骤二:调用ObjectInputStream对象的readObject()得到序列化的对象。


image.png

控制台只输出了Person的信息,没有输出构造方法中的内容,说明反序列化的对象是由 JVM 自己生成的,不通过构造方法生成。


Java 中 IO 流分为几种?


  • 按照流的流向分,可以分为输入流和输出流
  • 按照操作单元划分,可以划分为字节流和字符流
  • 按照流的角色划分节点流和处理流(包装流)


Java IO 流共涉及 40 多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java I0 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的


  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。


按照操作方式分类结构图:


image.png

按照角色划分:

image.png

既然有了字节流,为什么还要有字符流?区别?


问题本质想问:不管是文件读写还是网络发送接收,信息的最小存储单元都是字节,那为什么 I/O 流操作要分为字节流操作和字符流操作呢?

因为字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。


总结:性能和使用更加方便两方面阐述。


如何选择?


  • 大多数情况下使用字节流会更好,因为大多数时候 IO 操作都是直接操作磁盘文件,所以这些流在传输时都是以字节的方式进行的
  • 为了提高性能,针对读写对象的不同,字节流可以采用带缓冲区的BufferedInputStream和BufferedOutputStream,字符流可以采用带缓冲区的BufferedReader和BufferedWriter。


java.io 包下有哪些流?


字节流和字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。关于Java的I/O需要注意的有两点:一是两种对称性(输入和输出的对称性,字节和字符的对称性);二是两种设计模式(适配器模式和装潢模式)。


字符流和字节流都有对应的缓冲流,字节流也可以包装为字符流,缓冲流带有一个 8KB 的缓冲数组,可以提高流的读写效率。除了缓冲流外还有过滤流 FilterReader、字符数组流 CharArrayReader、字节数组流 ByteArrayInputStream、文件流 FileInputStream 等。


ps:BufferedReader属于处理流中的缓冲流,可以将读取的内容存在内存里面,有readLine()方法,它,用来读取一行


什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?


  • 节点流:   直接与数据源相连,用于输入或者输出,常见涉及操作:文件操作、管道操作与数组操作。
  • 处理流:在节点流的基础上对之进行加工,进行一些功能的扩展,常见操作:缓冲操作、对象序列化操作、转化操作、打印控制与基本数据类型操作
  • 处理流的构造器必须要 传入节点流的子类


什么是缓冲区?有什么作用?


  • 缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性。
  • 针对读写对象的不同,字节流可以采用带缓冲区的BufferedInputStream和BufferedOutputStream,字符流可以采用带缓冲区的BufferedReader和BufferedWriter。


流一般需要不需要关闭,如果关闭的话在用什么方法,一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是怎么关闭的?


  • 流一旦打开就必须关闭,使用close方法
  • 放入finally语句块中(finally 语句一定会执行)
  • 调用的处理流就关闭处理流
  • 多个流互相调用只关闭最外层的流


文件操作使用的流


Filter Stream是一种IO流主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能。


ps:FileInputStream和FileOutputStream是什么?


这是在拷贝文件操作的时候,经常用到的两个类。


  • 在处理小文件的时候,它们性能表现还不错(针对字符文件,FileReader/FileWriter)。
  • 在大文件的时候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)


说说管道流(Piped Stream)


  • 有四种管道流, PipedInputStream, PipedOutputStream, PipedReader 和 PipedWriter.
  • 在多个线程或进程中传递数据的时候管道流非常有用。


键盘获取输入的两种方式?


注意:这里的输入(和输出)针对的是内存,类似反序列化将对象流还原为对象的,创建输入流,调用readObject(),写入内存。

// Scanner:用来包装System.in流,很方便地将输入的String字符串转换成需要的数据类型。
Scanner input = new Scanner(System.in);
String s  = input.nextLine();
input.close()
// BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();


System.out.println()是什么?


PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应该将输出流包装成PrintStream后进行输出。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream.


println是PrintStream的一个方法。out是一个静态PrintStream类型的成员变量,System是一个java.lang包中的类,用于和底层的操作系统进行交互。

相关文章
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
80 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
3月前
|
安全 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版)
|
2月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
37 1
|
2月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
85 1
|
2月前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
50 0
|
3月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
2月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
38 0
|
3月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
4月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
49 2