• Java输入输出流


    问题及答案来源自《Java程序员面试笔试宝典》第四章 Java基础知识 4.7输入输出流

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

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

    • 字节流以字节为(8bt)单位,字符流以字符为(16bit)单位。
    • 字节流包括两个抽象类:InputStream(输入流)和OutputStream(输出流)
    • 字符流包括两个抽象类:Reader(输入流)和Writer(输出流)

    字节流和字符流主要区别:

    字节流在处理输入输出时不会用到缓存,而字符流用到了缓存

    常见笔试题 - Java中有几种类型的流?

    常见的流有两种:字节流和字符流,字节流继承于InputStream(输入流)和OutputStream(输出流),字符流

    继承于Reader(输入流)和Writer(输出流),在java.io包中还有许多其他的流,流的主要作用是为了改善程序性能并且使用方便

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

    Java中管理文件和文件夹的类是File类,File类常用方法:

    • File(String pathname):根据指定路径创建File对象
    • createNewFile():若目录或文件存在返回false,否则创建文件或文件夹
    • delete():删除文件或文件夹
    • isFile():判断这个对象表示的是否是文件
    • isDirectory():判断这个对象表示的是否是文件夹
    • listFiles():若对象表示目录,则返回目录中所有文件的File对象
    • mkdir():根据当前对象指定的路径创建目录
    • exists():判断对象对应的文件是否存在

    常见笔试题 - 如何列出某个目录下的所有目录和文件?

    详情见代码如下:

     1 import java.io.File;
     2 
     3 public class useListFiles {
     4     public static void main(String[] args) {
     5         File file = new File("D:\test");
     6         // 判断目录是否存在
     7         if(!file.exists()){
     8             System.out.println("directory is empty!");
     9             return;
    10         }
    11         File[] fileList = file.listFiles();
    12         for(int i=0; i<fileList.length; i++){
    13             // 判断是否为目录
    14             if(fileList[i].isDirectory()){
    15                 System.out.println("directory is: " + fileList[i].getName());
    16             } else{
    17                 System.out.println("file is: " + fileList[i].getName());
    18             }
    19         }
    20     }
    21 }

    3、Java Socket是什么?

    什么是Socket:

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket

    Socket也称为套接字,可以用来实现不同虚拟机或不同计算机之间的通信

    Java中的Socket:

    • 面向连接的Socket通信协议(TCP)
    • 面向无连接的Socket通信协议(UDP)
    • 任何一个Socket都是由IP地址和端口号唯一确定的

    基于TCP的通信过程:

    首先Server(服务器)Listen(监听)指定的某个端口(建议使用大于1024的端口)是否有连接请求;

    然后Client(客户端)向Server端发出连接请求(Connect);最后Server端向Client端返回Accept消息(接受)

    一个连接就建立起来了,会话立即产生,此时Server端和Client端都可以通过Send、Write等方法与对方通信

    socket生命周期三个阶段:

    • 打开Socket
    • 使用Socket收发数据
    • 关闭Socket

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

    常见笔试题 - 用Socket实现客户端和服务端的通信,要求客户发送数据后能返回相同的数据

    首先创建一个名为Server.java的服务器端程序:

     1 import java.io.*;
     2 import java.net.*;
     3 
     4 public class Server {
     5     public static void main(String[] args) {
     6         BufferedReader br = null;
     7         PrintWriter pw = null;
     8         try{
     9             ServerSocket server = new ServerSocket(8888);
    10             Socket socket = server.accept();
    11             // 获取输入流
    12             br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    13             // 获取输出流
    14             pw = new PrintWriter(socket.getOutputStream(), true);
    15             String s = br.readLine();    // 获取接收的数据
    16             pw.println(s);                // 发送相同的数据给服务端
    17         } catch(Exception e){
    18             e.printStackTrace();
    19         } finally{
    20             try{
    21                 br.close();
    22                 pw.close();
    23             } catch(Exception e){
    24                 e.printStackTrace();
    25             }
    26         }
    27     }
    28 }

    然后创建一个名为Client.java的客户端程序:

     1 import java.io.*;
     2 import java.net.*;
     3 
     4 public class Client {
     5     
     6     public static void main(String[] args) {
     7         BufferedReader br = null;
     8         PrintWriter pw = null;
     9         try{
    10             Socket socket = new Socket("localhost", 8888);
    11             // 获取输入流与输出流
    12             br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    13             pw = new PrintWriter(socket.getOutputStream(), true);
    14             // 向服务器发送数据
    15             pw.println("Hello");
    16             String s = null;
    17             while(true){
    18                 s = br.readLine();
    19                 if(s!=null){
    20                     break;
    21                 }
    22             }
    23             System.out.println(s);
    24         } catch (Exception e) {
    25             e.printStackTrace();
    26         } finally{
    27             try{
    28                 br.close();
    29                 pw.close();
    30             } catch(Exception e){
    31                 e.printStackTrace();
    32             }
    33         }
    34     }
    35 }

    最后启动服务器端程序,然后运行客户端程序,客户端会把从服务器转发过来的数据都打印出来

    4、Java NIO是什么?

    NIO与IO:

    NIO是指Nonblocking IO,指的是非阻塞IO

    阻塞是指暂停一个线程的执行以等待某个条件的发生,例如某资源就绪

    当处理多个连接时用到多线程时,阻塞会导致大量线程进行上下文切换,使得程序运行效率底下

    而NIO可以解决这个问题,NIO通过Selector、Channel和Buffer来实现非阻塞的IO操作

    NIO原理:

    NIO的实现主要采用了Reactor(反应器)模式,这个设计模式和Observer(观察者)模式类似,只不过

    Observer模式只能处理一个事件源,而Reactor设计模式可以处理多个事件源

    NIO与传统的Socket方式比,由于NIO采用了非阻塞的方式,在处理大量并发请求时使用NIO比使用

    Socket的效率高的多!

    5、什么是Java序列化?

    Java提供了两种对象持久化的方法:序列化和外部序列化

    (1)序列化

    序列化:把对象的状态写在流里进行网络传输,或者保存到文件、数据库等系统里,在必要的时候可以

    把流读取出来重新构造一个相同的对象

    实现序列化:

    • 所有实现序列化的类必须实现Serializable接口
    • 使用输出流(FileOutputStream)来构造一个ObjectOutputStream对象
    • 接着使用该对象的writeObject方法将obj对象写出(保存其状态)

    序列化的两个特点:

    • 一个类能被序列化,那么它的子类也能被序列化
    • 由于static代表类的成员,transient代表对象的临时数据,这两种类型的数据成员是不能被序列化的

    序列化实例:

     1 import java.io.*;
     2 
     3 public class People implements Serializable{
     4     public String name;
     5     public int age;
     6     
     7     public People(){
     8         this.name = "xxx";
     9         this.age = 18;
    10     }
    11     
    12     public static void main(String[] args) {
    13         People p = new People();
    14         ObjectOutputStream oos = null;
    15         ObjectInputStream ois = null;
    16         try{
    17             // 序列化
    18             FileOutputStream fos = new FileOutputStream("people.out");
    19             oos = new ObjectOutputStream(fos);
    20             oos.writeObject(p);
    21             oos.close();
    22         } catch (Exception e) {
    23             e.printStackTrace();
    24         }
    25         People p1;
    26         try{
    27             // 反序列化
    28             FileInputStream fis = new FileInputStream("people.out");
    29             ois = new ObjectInputStream(fis);
    30             p1 = (People)ois.readObject();
    31             System.out.println(p1.name + " - " + p1.age);
    32         } catch (Exception e) {
    33             e.printStackTrace();
    34         }
    35     }
    36 }

    (2)外部序列化

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

    接口如下:

    1 public interface Externalizable extends Serializable{
    2     void readExternal(ObjectInput in);
    3     void writeExternal(ObjectOutput out);
    4 } 

    外部序列化和序列化的主要区别:

    序列化是内置的API,只要实现Serializable接口就可以使用,不需要编写具体代码就可以实现对象的序列化

    而外部序列化中的读写接口必须由开发人员完成,难度更大,但更灵活,可以选择只持久化部分成员

    引申 - 在用接口Serializable实现序列化时,类中的所有属性都会被序列化,那么怎么样才能只序列化部分属性?

    • 用transient来控制序列化的属性,被transient修饰的属性是临时的,不会被序列化
    • 实现Externalizable接口,开发人员根据实际需求实现readExternal和writeExternal方法来控制序列化的属性
  • 相关阅读:
    bootstrap学习笔记一: bootstrap初认识,hello bootstrap(下)
    bootstrap学习笔记一: bootstrap初认识,hello bootstrap(上)
    AutoCompleteTextView的使用
    常用的android弹出对话框
    PopupWindow的使用
    linux udev、mdev 介绍
    linux 守护进程编程
    linux 下的文件目录操作之遍历目录
    linux 下查找图片文件方法
    linux 内核 zImage 生成过程分析
  • 原文地址:https://www.cnblogs.com/wyb666/p/10344062.html
Copyright © 2020-2023  润新知