《Java网络编程》读书笔记(一)

Java的I/O建立于stream(流)之上,所有的输出流和输入流都有各自的相同的读写方法,这也是Java面向接口编程的优势,这也是面向对象编程思想里面“封装”的思想!

一、Java网络编程里几个“名词”和常识:

(1)过滤器(filter):可以串链到输入流或者输出流上。顾名思义,可以通过使用filter可以修改数据(加密、压缩)、或者转换数据格式;

(2)阅读器(reader)和writer(书写器):同filter类似,也可以串链到流上。不同的是,读写器只是用于读/写字符,而不是字节(流处理的数据类型是字节)【读写器可以认为是和流在统计level】。

注意:串链这个词很好,表示filter和读写器都可以像链表这种形式一样,一个接一个的调用!

(3)流是同步的:当线程请求一个流操作(读/写)数据时,它是阻塞的,不能做其他事情。(Java也支持使用通道和缓冲区的非阻塞I/O,不在讨论范围!)

二、JavaI/O类结构

首先摘录一些《Think in Java》的内容:

(1)自InputStream/Reader派生而来的类都有read()基本方法,自OutputStream/Writer派生而来的类都有write()方法。

(2)很少用单一的流来创建流对象,通过叠合多个对象来达到目的(装饰器设计模式,以后会专门开一个设计模式专题)!

InputStream的作用是从不同数据源获取数据,下面看看具体有哪些:

OutputStream

     

(3)现在来看看“装饰器(filter)”:他有两个类,分别是FilterInputStream和FilterOutputStream,这两者分别从基类InputStream和OutputStream继承而来。

FilterInputStream类型:

FilterOutputStream类型

4)关于PrintStream和PrintWriter的比较

PrintStream有两个问题:

a. 它会捕捉所有的IOExceptions;

b. 为完全国际化,不能以平台无关的方式处理换行动作(我们经常看到的System.out.print()就是基于PrintStream的)

PrintStream是一个OutputStream,PrintWriter有一个接受OutputStream的构造器,因此完全可以把System.out转换成PrintWriter。

(5)Reader 和 Writer

目的:设计Reader 和 Writer的初衷是为了国际化,老式的I/O继承层次结构仅支持8位的字节流,不能不能处理16位的Unicode字符,Java的char类型也是Unicode类型。

适配器:为了将“字节”和“字符”的使用结合起来,可以使用InputStreamReader和OutputStreamWriter类将InputStream和OutputStream转换成Reader和Writer。

使用意见:尽量尝试使用Reader和Writer,不行则使用流式结构。

下面看看流和读/写器的对比:


相应的过滤器结构:


三、I/O操作实例

1. 输入文件:可以使用以String和File对象为参数的FileReader;为了提高速度,可以使用BufferedReader,示例如下:

package zy.io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedInputFile {

	public static void main(String[] args) throws IOException {
		//用的是相对路径
		System.out.print(read("src/zy/io/BufferedInputFile.java"));
	}
	
	public static String read(String filename) throws IOException {
		BufferedReader reader = new BufferedReader(
				new FileReader(filename));
		String s;
		StringBuilder builder = new StringBuilder();
		while ((s = reader.readLine()) != null) {
			builder.append(s + "\n");
		}
		reader.close();
		return builder.toString();
	}

}
2. 从内存输入:将内存中的某个数据发送到控制台

package zy.io;

import java.io.IOException;
import java.io.StringReader;

public class MemoryInput {

	public static void main(String[] args) throws IOException {
		StringReader reader = new StringReader(
				BufferedInputFile.read("src/zy/io/MemoryInput.java"));
		int c;
		while ((c = reader.read()) != -1) {
			System.out.print((char)c);
		}
	}

}
3. 格式化内存输入:使用DataInputStream类,这是面向字节的。这里提供两种方式,请见注释部分:

package zy.io;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;

public class FormattedMemoryInput {

	public static void main(String[] args) throws IOException {
		DataInputStream in = new DataInputStream(new ByteArrayInputStream(
				BufferedInputFile.read("src/zy/io/FormattedMemoryInput.java").getBytes()));
		
		//available()的字面意思是:在不阻塞的情况下锁能读取的字节数!
		while (in.available() != 0) {
			System.out.print((char)in.readByte());
		}		
		//任何字节的值都是合法的,返回值不能不用于检测输入是否结束,因此使用了try catch 块
       /*try {
			DataInputStream in = new DataInputStream(new ByteArrayInputStream(
					BufferedInputFile.read("src/zy/io/FormattedMemoryInput.java").getBytes()));
			while (true) {
				System.out.print((char)in.readByte());
			}
		} catch (EOFException e) {
			System.err.println("End of file");
		}*/
	}

}
4. 缓冲输出文件:当输出文件时,需要调用close()方法,因为在缓存区可能还有数据没有被写入;当然也可以调用flush()方法,强制清空,并将缓存的数据发送,一般情况下推荐close()就可以了,相当于一次flush(),而且流也关闭了,不会占据内存资源,但是当需要保存流的时候,就应该调用flush(),可以保证数据的完整性!

package zy.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;

public class BasicFileOutput {

	private static String file = "BasicFileOutput.out";
	public static void main(String[] args) throws IOException {
		
		BufferedReader reader = new BufferedReader(
				new StringReader(BufferedInputFile.read("src/zy/io/BasicFileOutput.java")));
//		PrintWriter writer = new PrintWriter(new 
//				BufferedWriter(new FileWriter(file)));
		
		// 这是快捷方式,不用自己的进行缓存,依旧以缓存的模式
		PrintWriter writer = new PrintWriter(file);
		int lineNum = 1;
		String s;
		while ((s = reader.readLine()) != null) {
			writer.println(lineNum++ + ": " + s);
		}
		//writer.flush();
		writer.close();
		System.out.println(BufferedInputFile.read(file));
	}

}

先写这些吧,后续有什么补充在跟上!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值