java socket 输入输出_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 importjava.io.File;2

3 public classuseListFiles {4 public static voidmain(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

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 classServer {5 public static voidmain(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(newInputStreamReader(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 classClient {5

6 public static voidmain(String[] args) {7 BufferedReader br = null;8 PrintWriter pw = null;9 try{10 Socket socket = new Socket("localhost", 8888);11 //获取输入流与输出流

12 br = new BufferedReader(newInputStreamReader(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 implementsSerializable{4 publicString name;5 public intage;6

7 publicPeople(){8 this.name = "xxx";9 this.age = 18;10 }11

12 public static voidmain(String[] args) {13 People p = newPeople();14 ObjectOutputStream oos = null;15 ObjectInputStream ois = null;16 try{17 //序列化

18 FileOutputStream fos = new FileOutputStream("people.out");19 oos = newObjectOutputStream(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 = newObjectInputStream(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 extendsSerializable{2 voidreadExternal(ObjectInput in);3 voidwriteExternal(ObjectOutput out);4 }

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

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

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

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

用transient来控制序列化的属性,被transient修饰的属性是临时的,不会被序列化

实现Externalizable接口,开发人员根据实际需求实现readExternal和writeExternal方法来控制序列化的属性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值