JAVA宝典----输入输出流(理解记忆)

目录

一、 Java IO流的实现机制是什么?

 二、Java中有几种类型的流?

三、管理文件和目录的类是什么?

 四、Java Socket是什么?

 五、什么是 JAVA NIO?

六、 什么是Java序列化?

(1)序列化(Serialization)

(2)外部序列化

七、在什么情况下需要使用该序列化呢?

九、System.out.println()方法使用需要注意哪些问题


一、 Java IO流的实现机制是什么?

        在Java语言中,输入和输出都被称为抽象的流,流可以被看作一组有序的字节集合,即数据在两设备之间的传输

        流的本质是数据传输,根据处理数据类型的不同,流可以分为两大类:字节流和字符流。字节流以字节(8bit)为单位,包含两个抽象类:InputStream(输入流)和OutputStream(输出流)。字符流以字符(16bit)为单位,根据码表映射字符,一次可以读多个字节,它包含两个抽象类:Reader(输入流)和Writer(输出流)。字节流和字符流最主要的区别为:字节流在处理输入输出时不会用到缓存,而字符流用到了缓存。每个抽象类都有很多具体的实现类。Java IO类在设计时采用了Decorator(装饰者)设计模式,以InputStream为例,介绍Decorator设计模式在IO类中的使用如下。

其中,ByteArrayInputStream、StringBufferInputStream、FileInputStream和PipedInputStream是Java提供的最基本的对流进行处理的类,FilterInputStream为一个封装类的基类,可以对基本的IO类进行封装,通过调用这些类提供的基本的流操作方法来实现更复杂的流操作。
使用这种设计模式的好处是可以在运行时动态地给对象添加一些额外的职责,与使用继承的设计方法相比,该方法具有很好的灵活性。

假如现在要设计一个输入流的类,该类的作用为在读文件时把文件中的大写字母转换成小写字母,把小写字母转换为大写字母。在设计时,可以通过继承抽象装饰者类(FilterInput-Stream)来实现一个装饰类,通过调用InputStream类或其子类提供的一些方法再加上逻辑判断代码从而可以很简单地实现这个功能

import java.io.*;public class test {public static void main(String[] args) {int c;try {InputStream is = new OwnInputStream(new BufferedInputStream(new FileInputStream("..\\base\\src\\test.txt ")));while ((c = is.read()) >= 0) {System.out.print((char) c);}is.close();} catch (IOException e) {System.out.println(e.getMessage());}}static class OwnInputStream extends FilterInputStream {public OwnInputStream(InputStream in) {super(in);}public int read() throws IOException {int c = 0;if ((c = super.read()) != -1) {//把小写转换为大写if (Character.isLowerCase((char) c))return Character.toUpperCase((char) c);//把大写转换为小写else if (Character.isUpperCase((char) c))return Character.toLowerCase((char) c);//如果不是字母,保持不变elsereturn c;} else {return -1;}}}
}


当文件 test . txt 中的内容为:jiayou12345时

程序输出为:JIAYOU12345

 二、Java中有几种类型的流?

        常见的流有两种,分别为字节流与字符流。其中,字节流继承于InputStream与OutputStream,字符流继承于Reader与Writer。在java.io包中还有许多其他的流,流的作用主要是为了改善程序性能并且使用方便。

三、管理文件和目录的类是什么?

        对文件或目录进行管理与操作在编程中有着非常重要的作用,Java提供了一个非常重要的类(File)来管理文件和文件夹,通过类不仅能够查看文件或目录的属性,而且还可以实现对文件或目录的创建、删除与重命名等操作。下面主要介绍File类中常用的几个方法

7ce95c727d3346438d6ae46278e8ef1e.jpg

 四、Java Socket是什么?

        网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket也称为套接字,可以用来实现不同虚拟机或不同计算机之间的通信。在Java语言中,Socket可以分为两种类型:面向连接的Socket通信协议(TCP,Transmission Control Protocol,传输控制协议)和面向无连接的Socket通信协议(UDP,User Datagram Protocol,用户数据报协议)。任何一个Socket都是由IP地址和端口号唯一确定的。

基于TCP的通信过程如下:首先,Server(服务器)端Listen(监听)指定的某个端口(建议使用大于1024的端口)是否有连接请求;其次,Client(客户)端向Server端发出Connect(连接)请求;最后,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了,会话随即产生。Server端和Client端都可以通过Send、Write等方法与对方通信。

Socket的生命周期可以分为3个阶段:打开Socket、使用Socket收发数据和关闭Socket。在Java语言中,可以使用ServerSocket来作为服务器端,Socket作为客户端来实现网络通信。

dd6970a54144416ab7dc2978290d60e0.jpg

 五、什么是 JAVA NIO?

        在非阻塞IO(Nonblocking IO,NIO)出现之前,Java是通过传统的Socket来实现基本的网络通信功能的。以服务器端为例,基本流程图如下图

1aa5521be88b44c09b543f068052b3b4.jpeg

 如果客户端还没有对服务器端发起连接请求,那么accept 就会阻塞(阻塞指的是暂停一个线程的执行以等待某个条件发生,例如某资源就绪)。如果连接成功,当数据还没有准备好时,对read的调用同样会阻塞。当要处理多个连接时,就需要采用多线程的方式,由于每个线程都拥有自己的栈空间,而且由于阻塞会导致大量线程进行上下文切换,使得程序的运行效率非常低下,因此在J2SE 1.4中引入了NIO来解决这个问题。

NIO通过Selector、Channel和Buffer来实现非阻塞的IO操作,其实现原理如图如下

3a57943092ee436795cefe6b83e53e20.jpeg

NIO非阻塞的实现主要采用了Reactor(反应器)设计模式,这个设计模式与Observer(观察者)设计模式类似,只不过Observer设计模式只能处理一个事件源,而Reactor设计模式可以用来处理多个事件源。
在上图中,Channel可以被看作一个双向的非阻塞的通道,在通道的两边都可以进行数据的读写操作。Selector实现了用一个线程来管理多个通道(采用了复用与解复用的方式使得一个线程能够管理多个通道,即可以把多个流合并成为一个流,或者把一个流分成多个流的方式),它类似于一个观察者。在实现时,把需要处理的Channel的IO事件(例如connect、read或write等)注册给Selector。Selector内部的实现原理为:对所有注册的Channel进行轮询访问,一旦轮询到一个Channe 1有注册的事件发生,例如有数据来了,它就通过传回Selection-Key的方式来通知开发人员对Channe 1进行数据的读或写操作。Key(由SelectionKey类表示)封装一个特定Channe 1和一个特定的selector之间的关系。这种通过轮询的方式在处理多线程请求时不需要上下文的切换,而采用多线程的实现方式在线程之间切换时需要上下文的切换,同时也需要进行压栈与弹栈操作。因此,NIO有较高的执行效率。

Buffer用来保存数据,可以用来存放从Channe 1读取的数据,也可以存放使用Channe 1进行发送的数据。Java提供了多种不同类型的Buffer,例如ByteBuffer、CharBuffer等,通过Buffer,大大简化了开发人员对流数据的管理。
NIO在网络编程中有着非常重要的作用,与传统的Socket方式相比,由于NIO采用了非阻塞的方式,在处理大量并发请求时,使用NIO要比使用Socket效率高出很多。

六、 什么是Java序列化?

Java提供了两种对象持久化的方式,分别为序列化和外部序列化。


(1)序列化(Serialization)


在分布式环境下,当进行远程通信时,无论是何种类型的数据,都会以二进制序列的形式在网络上传送。序列化是一种将对象以一连串的字节描述的过程,用于解决在对对象流进行读写操作时所引发的问题。序列化可以将对象的状态写在流里进行网络传输,或者保存到文件、数据库等系统里,并在需要时把该流读取出来重新构造一个相同的对象。
如何实现序列化呢?其实,所有要实现序列化的类都必须实现Serializable接口,Serializ-able接口位于java.lang包中,它里面没有包含任何方法。使用一个输出流(例如FileOutput-Stream)来构造一个ObjectOutputStream(对象流)对象,紧接着,使用该对象的writeObject(Object obj)方法就可以将obj对象写出(即保存其状态),要恢复时可以使用其对应的输入流。
序列化有以下两个特点:
1)如果一个类能被序列化,那么它的子类也能够被序列化。
2)由于static(静态)代表类的成员,transient(Java语言关键字,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。)代表对象的临时数据,因此被声明为这两种类型的数据成员是不能够被序列化的。

Java提供了多个对象序列化的接口,包括ObjectOutput、ObjectInput,ObjectOutputStream和ObjectInputStream。

由于序列化的使用会影响系统的性能,因此如果不是必须要使用序列化,应尽可能不要使用序列化。

(2)外部序列化


Java语言还提供了另外一种方式来实现对象持久化,即外部序列化

外部序列化与序列化主要的区别在于序列化是内置的API,只需要实现Serializable接口,开发人员不需要编写任何代码就可以实现对象的序列化,而使用外部序列化时,Externalizable接口中的读写方法必须由开发人员来实现。因此与实现Serializable接口的方法相比,使用Ex-ternalizable编写程序的难度更大,但是由于把控制权交给了开发人员,在编程时有更多的灵活性,对需要持久化的那些属性可以进行控制,可能会提高性能。

七、在什么情况下需要使用该序列化呢?


1)需要通过网络来发送对象,或对象的状态需要被持久化到数据库或文件中。
2)序列化能实现深复制,即可以复制引用的对象。
与序列化相对的是反序列化,它将流转换为对象。在序列化与反序列化的过程中,serial-VersionUID起着非常重要的作用,每个类都有一个特定的serialVersionUID,在反序列化的过程中,通过serialVersionUID来判定类的兼容性。如果待序列化的对象与目标对象的serialVersion-UID不同,那么在反序列化时就会抛出InvalidClassException异常。作为一个好的编程习惯,最好在被序列化的类中显式地声明serialVersionUID(该字段必须定义为static final)。

自定义seri-alVersionUID主要有如下3个优点
1)提高程序的运行效率。如果在类中未显式声明serialVersionUID,那么在序列化时会通过计算得到一个serialVersionUID值。通过显式声明serialVersionUID的方式省去了计算的过程,因此提高了程序的运行效率。

2)提高程序不同平台上的兼容性。由于各个平台的编译器在计算serialVersionUID时完全有可能会采用不同的计算方式,这就会导致在一个平台上序列化的对象在另外一个平台上将无法实现反序列化的操作。通过显式声明serialVersionUID的方法完全可以避免该问题的发生。


3)增强程序各个版本的可兼容性。在默认情况下,每个类都有唯一的serialVersionUID,因此,当后期对类进行修改时(例如加入新的属性),类的serialVersionUID值将会发生变化,这将会导致类在修改前对象序列化的文件在修改后将无法进行反序列化操作。同样,通过显式声明serialVersionUID也会解决这个问题。八、在用接口Serializable实现序列化时,这个类中的所有属性都会被序列化,那么怎样才能实现只序列化部分属性呢?
一种方法为实现Externalizable接口,开发人员可以根据实际需求来实现readExternal与writeExternal方法来控制序列化与反序列化所使用的属性,这种方法的缺点为增加了编程的难度。另一种方法为使用关键字transient来控制序列化的属性。被transient修饰的属性是临时的,不会被序列化。因此,可以通过把不需要被序列化的属性用transient来修饰。

九、System.out.println()方法使用需要注意哪些问题


        Java中的System.out.println()方法提供了一种非常有效简单的方法来实现控制台的输出,该方法默认接收一个字符串类型的变量作为参数。当然,在使用时可以传递任意能够转换为String类型的变量作为参数(例如基本类型int,或者一个实现toString方法的自定义类等)如

System. out. println(1 +2 +" ");

System. out. println(" " +1 +2);

输出为 :3

               12

首先计算1+2,由于它们都是整型变量,因此计算结果为3,接着计算3+"",由于""是字符串,因此首先会把3转换为字符串,其次执行加操作,计算结果为“3”,因此输出结果为3。对于最后一个输出语句来说,首先计算""+1,会把1转换为字符串,其次执行加操作,计算结果为“1”,同理,接着计算“1”+2结果为“12”,因此输出结果为12。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/89393.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

连续两年增收不增利,比亚迪电子靠新能源汽车业务再次起飞?

在净利润连续两年下挫之后,比亚迪电子(00285.HK)终于迎来了好消息。 不久前比亚迪电子发布2023年中期盈利预告显示,上半年净利润同比增加115%-146%(2022年上半年的净利润显示6.34亿元)。 这主要受益于大客…

tomcat多实例与动静分离

实验:在一台虚拟机上配置多台tomcat 1.配置 tomcat 环境变量 vim /etc/profile.d/tomcat.sh source /etc/profile.d/tomcat.sh 2.修改 tomcat2 中的 server.xml 文件,要求各 tomcat 实例配置不能有重复的端口号 vim /usr/local/tomcat/tomcat2/conf/…

山东布谷科技直播平台搭建游戏开发技术分享:数据存储的重要意义

在市场上的热门的直播平台中,有很多小程序为用户提供各种各样的功能,这其中就有很多游戏小程序,当今社会独生子女众多,很多作为独生子女的用户都会去选择一个能够社交互动的APP来填补内心的空虚,而直播平台的实时互动的…

Node.js学习笔记-04

这第九章也是个大重点 九、玩转进程 Node在选型时决定在V8引擎之上构建,也就意味着它的模型与浏览器类似。 本章关于进程的介绍和讨论将会解决如下两个问题: 单进程单线程并非完美,如今CPU基本均是多核的,真正的服务器&#xf…

MySQL 8 group by 报错 this is incompatible with sql_mode=only_full_group_by

文章目录 sql_mode配置ONLY_FULL_GROUP_BYSTRICT_TRANS_TABLESNO_ZERO_IN_DATENO_ZERO_DATEERROR_FOR_DIVISION_BY_ZERONO_AUTO_CREATE_USERNO_ENGINE_SUBSTITUTION 局部修改配置windows修改配置Linux修改配置 sql_mode配置 ONLY_FULL_GROUP_BY 用于控制是否允许对查询结果进…

springboot汽车租赁后台java出租客户管理jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 springboot汽车租赁后台 系统有1权限:管理…

mysql索引的数据结构(Innodb)

首选要注意,这里的数据结构是存储在硬盘上的数据结构,不是内存中的数据结构,要重点考虑io次数. 一.不适合的数据结构: 1.Hash:不适合进行范围查询和模糊匹配查询.(有些数据库索引会使用Hash,但是只能精准匹配) 2.红黑树:可以范围查询和模糊匹配,但是和硬盘io次数比较多. 二…

NLP文本匹配任务Text Matching [有监督训练]:PointWise(单塔)、DSSM(双塔)、Sentence BERT(双塔)项目实践

NLP文本匹配任务Text Matching [有监督训练]:PointWise(单塔)、DSSM(双塔)、Sentence BERT(双塔)项目实践 0 背景介绍以及相关概念 本项目对3种常用的文本匹配的方法进行实现:Poin…

【闲侃历史】 唐朝----安史之乱那些事(1)

说到安史之乱,可谓是唐朝最乱的一段时期,据说唐朝当时也就5000多万人,而经历了这一战,人口只剩1000多万人了。著名的杨国忠和杨贵妃也是在这个时候死的。这个系列我们就先来侃侃发起安史之乱的两个人----安禄山和史思明 一. 安禄…

Django的简介安装与配置及两大设计模式

一.Djang的介绍 1.Django是什么 Django 是使用 Python 语言开发的一款免费而且开源的 Web 应用框架。 由于 Python 语言的跨平台性,所以 Django 同样支持 Windows、Linux 和 Mac 系统。 在 Python 语言炽手可热的当下,Django 也迅速的崛起,在…

LeetCode150道面试经典题-- 有效的字母异位词(简单)

1.题目 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。 2.示例 s"adasd" t"daads" 返回true s"addad" t &q…

最小生成树(Kruskal)克鲁斯卡尔算法

算法步骤总共分为两步,由并查集实现 第一步(把所有的边按边长的大小进行排序) 第二步(如果两个点不连通就把两点之间的边加上再把两个点连通) 当放入的边数为点数减去一时就代表已经全部连通 例题一(859. …

[Mongodb 5.0]聚合操作

本文对应Aggregation Operations — MongoDB Manual 正文 此章节主要介绍了Aggregation Pipeline,其实就是将若干个聚合操作放在管道中进行执行,每一个聚合操作的结果作为下一个聚合操作的输入,每个聚合指令被称为一个stage。 在正式开始学…

电压放大器和电荷放大器区别是什么意思

电压放大器和电荷放大器是两种常见的信号放大器。它们的区别主要在于其输入端口所呈现的电路特性不同。 电压放大器的介绍 电压放大器是一种将输入信号的电压增益放大的电路元件,其输入端口呈现高阻抗特性。即在输入端口上,电压放大器所对应的电路模型中…

探索数据之美:初步学习 Python 柱状图绘制

文章目录 一 基础柱状图1.1 创建简单柱状图1.2 反转x和y轴1.3 数值标签在右侧1.4 演示结果 二 基础时间线柱状图2.1 创建时间线2.2 时间线主题设置取值表2.3 演示结果 三 GDP动态柱状图绘制3.1 需求分析3.2 数据文件内容3.3 列表排序方法3.4 参考代码3.5 运行结果 一 基础柱状图…

【Android】MVC,MVP,MVVM三种架构模式的区别

MVC 传统的代码架构模式,仅仅是对代码进行了分层,其中的C代表Controller,控制的意思 将代码划分为数据层,视图层,控制层,三层之间可以任意交互 MVP MVP是在MVC基础上改进而来的一种架构,其中的…

微信开发之一键退出群聊的技术实现

简要描述: 退出群聊 请求URL: http://域名地址/quitChatRoom 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wI…

0基础学C#笔记09:希尔排序法

文章目录 前言一、希尔排序的思想二、使用步骤总结 前言 希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。也就是说,原数组的一个元素如果距离它…

React源码解析18(3)------ beginWork的工作流程【mount】

摘要 OK,经过上一篇文章。我们调用了: const root document.querySelector(#root); ReactDOM.createRoot(root)生成了FilberRootNode和HostRootFilber。 并且二者之间的对应关系也已经确定。 而下一步我们就需要调用render方法来讲react元素挂载在ro…

gitee分支合并

合并dev分支到master(合并到主分支) git checkout master git merge dev //这里的dev表示你的分支名称 git push //推送到远程仓库 效果如下图 不报错就表示推送成功了,希望能帮助各位小伙伴