Java基础系列之输入输出流

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

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

根据处理类型的不同,流可以分为两大类:字节流和字符流。字节流以字节(8bit)为单位,包含两个抽象类:InputStream(输入流)和OutputStream(输出流)。字符流以字(16bit)为单位,根据码表映射字符,一次可读多个字节,包含两个抽象类:Reader(输入流)和Writer(输出流)。

字符流和字节流最主要的区别:字节流在初六输入输出数据时不会用到缓存,字符流用到了缓存。

Java IO类在设计时采用了Decorator(装饰者)设计模式。以InputStream为例,介绍Decorator设计模式在IO类中的使用。

在这里插入图片描述

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

Java提供了File类来管理文件和文件夹,通过类能够查看文件或目录的属性,而且还可以实现对文件或目录的创建、删除与重命名等操作。

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

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

package org.base;

import java.io.File;

public class TestFile {
	public static void main(String[] args) {
		File file = new File("D:");
		// 判断目录是否存在
		if(!file.exists()){
			System.out.println("Directory is empty!");
			return;
		}
		File[] files = file.listFiles();
		for (int i = 0; i < files.length; i++) {
			if(files[i].isDirectory()){
				System.out.println("directory is:" + files[i].getName()); 
			} else {
				System.out.println("file is:" + files[i].getName()); 
			}
		}
	}
}

运行结果:显示D盘下所有的文件名称

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(接收)消息。一个连接就建立起来了,会话随机产生。

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

class Server {
	public static void main(String[] args) {
		BufferedReader br = null;
		PrintWriter pw = null;
		try {
			ServerSocket server = new ServerSocket(2000);
			Socket socket = server.accept();
			// 获取输入流
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			// 获取输出流
			pw = new PrintWriter(socket.getOutputStream(), true);
			String s = br.readLine();// 获取接收的数据
			pw.println(s);
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			try {
				br.close();
				pw.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
}
package org.base;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import org.junit.Test;

class Cilent {
	@Test
	public static void main(String[] args) {
		BufferedReader br = null;
		PrintWriter pw = null;
		try {
			Socket socket = new Socket("localhost", 2000);
			// 获取输入输出流
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			pw = new PrintWriter(socket.getOutputStream(), true);
			pw.println("Hello");
			String s = null;
			while (true) {
				s = br.readLine();
				if(s != null) {
					break;
				}
			}
			System.out.println(s);
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			try {
				br.close();
				pw.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
}

最后启动服务器程序,然后运行客户端程序,客户端将会把从服务器转发过来的“Hello”打印出来。

7.4 Java NIO是什么?

在非阻塞(Nonblocking IO,NIO)出现之前,Java是通过传统的Socket来实现基本的网络通信功能的。
如果客户端还没有对服务器发起连接请求,那么accept就会阻塞(阻塞指的是暂停一个线程的执行以等待某个条件发生,例如某资源就绪)。如果连接成功,当数据还没有准备好时,对read的调用同样会阻塞。当处理多个线程时,就需要采用多线程的方式,由于每个线程都拥有自己的栈空间,而且由于阻塞会导致大量线程进行上下文切换,使得程序的运行效率非常低下。

NIO通过Selector、Channel和Buffer来实现非阻塞的IO操作。
Java面试宝典 121页
NIO在网络编程中有着非常重要的作用,与传统的Socket方式相比,由于NIO采用了非阻塞的方式,在处理大量并发送请求时,使用NIO要比使用Socket效率高处很多。

7.5 什么是Java序列化?

Java提供了两种对象持久化的方式,分别是序列化和外部序列化。
(1)序列化(Serialization)
在分布式环境中,当进行远程通信时,无论是何种类型的数据,都会以二进制序列的形式在网络上传送。序列化是一种将对象以一连串的字节描述的过程,用于解决在对对象流进行读写操作时所引发的问题。序列化可以将对象的状态写在流里进行网络传输,或者保存在文件、数据库等系统里,并在需要时把该流读取出来重新构造一个相同的对象。

如何实现序列化?

所有要实现序列化的类都必须实现Serialization接口,Serializable接口位于java.lang包中,它里面没有包含任何方法。

序列化有以下两个特点:

  1. 如果一个类能被序列化,那么它的子类也能够被序列化。
  2. 由于static(静态)代表类的成员,transient(Java的关键字,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。)代表对象的临时数据,因此被声明为这两种类中的数据成员是不能够被序列化的。

什么时候需要使用序列化?

  1. 需要通过网络来发送对象,或对象的状态需要被持久化到数据库或文件中。
  2. 序列化能实现深复制,即可以复制引用的对象。

外部序列化与序列化的区别主要是序列化是内置的API,序列化只需要实现Serialization接口,实现外部序列化Externalizable接口中的读写方法必须由开发人员来实现。

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

System.out.println()方法默认接收了一个字符串类型的变量作为参数。使用时可以传递任意能够转换为String类型的变量作为参数。

public class Test {
	public static void main(String[] args) {
		System.out.println(1 + 2 + "");
		System.out.println("" + 1 + 2);
	}
}

运行结果:3
     12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值