(一)socket·磨刀不误砍柴工 之 Java IO

版权声明:本文为博主原创文章,如有错误劳烦指正。转载请声明出处,便于读取最新内容。——Bestcxx https://blog.csdn.net/bestcxx/article/details/86697259

前言

本文不会对 Java IO 进行系统性介绍,因为这一块内容实在是够喝一壶的,但是对于 socket 编程来说,Java IO 的知识是必不可少的。本文就 Java IO 的基本内容进行介绍。

IO

简单来说就是输入输出数据流

Java IO

对于 Java IO ,需要了解到的是,Java IO 是一个很大的体系,但是究其根本依旧是读、写两个,此外Java IO 中有缓冲区一说,于是就有了 flush ,即清空缓冲区一说。
IO 是一个很占用资源的操作,尽管这些资源也可以被自身释放掉,但是为了保证代码的健壮性,务必养成用完主动关闭的释放资源的好习惯。

字节和字符

字节 Byte,一个字节占8位
在文本类内容中,我们会遇到各种编码格式,比如 GBK、UTF8 等
Java IO 将字节的处理和字符的处理分为了两类,但是在底层,都是按照字节来进行处理的
换而言之,字节和字符的处理是有转化方法的

字节流的两个抽象类

围绕字节输入输出流,Java IO 提供了两个抽象类,java.io.InputStream 和 java.io.OutputStream ,其下有诸多的子类,建议用 IDEA 查看这两个类的源码。

字节输入流

java.io.InputStream

inputStream.read();//返回 inputStream对象 一个字节的值
inputStream.read(byte[]);//将 inputStream 对象 写入字节数组 byte[] ,并返回写入的字节数
inputStream.close();//关闭
字节输出流

java.io.OutputStream

 outputStream.write(byte[]);//将 字节数组 byte[] 写入 outputStream对象
 outputStream.close();//关闭
字符流的两个抽象类

围绕字符输入流,比如文字,文本等,Java IO 提供了两个抽象类 java.io.Reader 和 java.io.Writer,对于文件的操作就是由这两个抽象类的子类完成的,建议使用 IDEA 查看源码

字符输入流

java.io.Reader

  reader.read();//返回 reader 对象的一个字符
        reader.read(char[]);//将 reader 对象写入 字符数组 char[] 并返回写入的字符数
        reader.close();//关闭
字符输出流

java.io.Writer

 writer.write(char[]);//将字符数组 char[] 写入到 writer 对象
        writer.flush();//清空缓存
        writer.close();//关闭
字符-Java 包含哪些种类的字符

Java 支持很多种类的字符,可以运行下面这段代码,获取直接去看源码
需要强调的是,这里并不包含 Unicode,Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,他只是一种标准,
Unicode标准提供了三种不同的编码格式,使用8位、16位和32位编码单元,分别为UTF-8、UTF-16、UTF-32,这三个是包含在 Java 支持的字符类型中的

public static void main(String [] args){
        SortedMap<String,Charset> map= Charset.availableCharsets();
         Collection<Charset> c=map.values();
        Iterator iterator=c.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
字符流和字节流相互转化

在实际使用中,我们总是会遇到文本传输的问题,这个时候我们总是需要将字节流转化为字符流来进行处理,以便于解决乱码和读取信息等问题。

字节流通向字符流的桥梁

java.io.InputStreamReader
在该类的源码中我们可以看到如下内容,可以将 InputStream 转化为 具体 Reader 的子类对象

//使用举例
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
//构造方法
public InputStreamReader(InputStream in) {··}

字符流通向字节流的桥梁

java.io.OutputStreamWriter
在该类的源码中我们可以看到如下内容,可以将 Writer 子类对象 写入 到 OutputSream对象

 //使用举例
 Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
 //构造方法
 public OutputStreamWriter(OutputStream out) {··}
 
Java 中的换行符

如何在 Java 中表示换行符? \n ,\r 还是 \r\n?
由于不同操作系统中换行符不同,所以我们用源码中的换行符,他是根据操作自动来自动获取的

java.security.AccessController.doPrivileged(new  sun.security.action.GetPropertyAction("line.separator"))
                    
BufferedReader.readLine 和 PrintWriter.println的妙用
BufferedReader.readLine

readLine 方法是一个阻塞方法,只有读到末尾、遇到换行符、或者操作中断,而我们一般会采用下面的方法来进行读操作
试想,在一个线程中,服务器端等待客户端发送信息,而客户端在等服务器端返回信息,那么真是一件很糟糕的事情了。
在 socket 编程中我们就会遇到这个问题,不过别担心。我们一起见证解决方案。

String str="";
for(;(str=bufferedReader.readLine())!=null;){
	System.out.println(str);               
}
PrintWriter.println

println() 不同于 System.out.println(),它的内部有一个 flush()和换行,所以你应该想到,它可以在 IO 缓存没有写满就发送数据,提高效率,同时,换行也会有换行符。
此外需要注意,flush()默认不开启,需要在声明 PrintWriter()对象时调用相应的构造方法
PrintWriter(writer,true);
否则需要手动调用 flush()发送缓存区的数据

//autoFlush 为true,调用 printf 或者 format 时会自动调用 flush()方法
public PrintWriter(Writer out,
                       boolean autoFlush) 
socket 获取 InputStream 和 OutputStream

一般而言,在socket 编程中,服务单获取客户端,客户端连接服务端,然后我们就对这个 socket 对象的输入输出流进行操作

获取 socket 客户端对象的输入流
//socket 表示客户端对象
socket.getInputStream();
获取 socket 客户端对象的输出流
//socket 表示客户端对象
socket.getOutputStream();

猜你喜欢

转载自blog.csdn.net/bestcxx/article/details/86697259
今日推荐