Java基础——输入输出流

目录

1.Java IO流的实现机制

2.管理文件的目录的类是什么

3.Java Socket是什么

4.Java NIO是什么

5.什么是Java序列化


1.Java IO流的实现机制

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

流可分为两大类:字节流和字符流。

字节流以字节(8bit)为单位,包含两个抽象类:InputStream(输入流)和OutputStream(输出流)

字符流以字符(16bit)为单位,一次可读多个字节,包含Reader(输入流)和Writer(输出流)

两者区别:字节流没有用到缓存,字符流用到了缓存。

Java IO类在设计时采用了Decorator(装饰者)设计模式,可以在运行时动态给对象添加一些额外的职责,于使用继承的设计方法相比,有很好的灵活性。

面试题:Java有几种类型的流?

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

再来一个问题:既然信息的最小存储单元是字节,已经有了字节流,为什么还要有字符流?

答:字符流通常是由Java虚拟机转换字节得到的,而这个过程通常又比较耗时,如果不知道编码更容易出现乱码问题。因此IO流直接提出了一个操作字符的接口,便于直接对字符进行操作。当涉及输入输出图片、音频文件时,用字节流比较好,如果涉及字符还是使用字符流比较好。

2.管理文件的目录的类是什么

File,通过该类不仅能够查看文件或目录的属性,而且可以实现对文件或目录的创建、删除与重命名等操作。

列出某个目录下所有目录和文件:

import java.io.File;
public class Test{
    public static void main(String[] args) {
        File file = new File("E:\\testFile");
        //判断目录是否存在
        if(!file.exists()){
            System.out.println("directory is empty!!!");
            return;
        }
        File[] fileList =file.listFiles();
        for (int i = 0; i < fileList.length; i++) {
            //判断是否为目录
            if(fileList[i].isDirectory()){
                System.out.println("directory is: "+fileList[i].getName());
            }else{
                System.out.println("file is: "+fileList[i].getName());
            }
        }
    }
}

结果:

 

 

3.Java Socket是什么

两个程序通过一个双向的通信连接实现数据交换,双向链路的一端称为一个Socket。Socket也称套接字,可实现不同虚拟机或不同计算机之间的通信。

Java语言中,Socket分为两种:面向连接Socket通信协议(TCP,传输控制协议)和面向无连接的Socket通信协议(UDP,用户数据报协议)。任何一个Socket都是由IP地址和端口号唯一确定的。

基于TCP的通信过程:

首先,Server端Listen指定的某个端口(建议大于1024)是否由连接请求;其次,Client端向Server端发出Connect请求;最后,Server端向Client端发回Accept消息。一个连接建立,会话产生。Server和Client可通过Send、Writer方法通信。

Socket生命周期可分为三个阶段:打开Socket、使用Socket收发数据、关闭Socket。

Java中,可使用ServerSocket作为服务器端,Socket作为客户端实现网络通信。

4.Java NIO是什么

在非阻塞IO(Nonblocking IO,NIO)出现之前,Java是通过传统的Socket来实现基本的网络通信功能的。

如果客户端没有对服务器端发起连接请求,那么accept就会阻塞(指暂停一个线程的执行以等待某个条件的发生,例如某资源就绪)。如果连接成功,当数据还没准备好,对read的调用也会阻塞。当采用多线程时,由于每个线程都有自己的栈空间,由于阻塞会造成大量线程上下文切换,程序运行效率低下。因此引入NIO解决这个问题

NIO通过Selector、Channel和Buffer来实现非阻塞的IO操作。

实现原理看的有点懵,以后补……

NIO采用非阻塞方式,在处理大量并发请求时,使用NIO比Socket效率高很多。

5.什么是Java序列化

Java中两种对象持久化方式 :序列化和外部序列化

1)序列化:

一种将对象以一连串的字节描述的过程,用于解决在对对象流进行读写操作时所引发的问题.

序列化可将对象的状态写在流里进行网络传输,或保存到文件、数据库等系统里,并在需要时把该流读取出来重新构造一个相同的对象。

实现序列化:必须实现Serializable接口,位于java.lang包中,没有任何方法。使用一个输出流(如FileOutputStream)来构造一个ObjectOutputStream(对象流),接着,使用该对象的writeObject方法可将obj对象写出(保存其状态),同理,恢复时使用其对应输入流。

序列化两个特点:1)一个类能被序列化,其子类也可以被序列化。2)static代表类的成员,transient代表对象的临时数据,被声明这两种类型的数据成员不能够被序列化。

使用序列化会影响系统性能,若不是必须尽可能不要使用,哪些情况需要使用序列化:1)需要痛过网络发送对象,或对象状态需要被持久化到数据库或文件中。2)序列化可实现深复制,复制引用的对象。

与序列化相对的是反序列化,它可将流转换为对象。转换过程中,serialVersionUID起非常重要的作用,通过serialVersionUID判定类的兼容性。如果待序列化对象与目标对象的serialVersionUID不同,就会抛InvalidClassException异常。最好在被序列化的类中显式声明serialVersionUID(该字段必须声明为static final)

自定义serialVersionUID有3个优点:

1.提高程序运行效率 2.提高程序不同平台的兼容性 3.增强程序各个版本的兼容性

 

2)外部序列化:

外部序列化和序列化主要区别就是序列化是内置的API,使用外部序列化时,Externalizable接口中的读写方法必须由开发人员实现,难度更大,但有更多的灵活性,可能会提高性能。

引申:怎么实现只序列化部分属性?

一种方法是实现Externalizable接口,开发人员根据实际需求实现readExternal与writeExternal方法控制使用的属性,缺点是增加了编程难度;第二种将不需要被序列化的属性用transient修饰,用transient修饰的属性是临的,不会被序列化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值