输入输出应用编程——4

节点流

File 文件
字符流
字节流
File 文件
FileReader FileWriter
FileInputStream FileOutputStream
内存数组
CharArrayReader
CharArrayWriter
ByteArrayInputStream
ByteArrayOutp
内存字串
StringReaderStringWriter
管道
PipedReader PipedWriter
PipedInputStreamPipedOutputStream

文件节点流

FileInputStream FileOutputStream 是文件字节流,是一种节点流
文件字节输入流的构造方法:
  • FileInputStream("文件名称"),如果文件不存在则FileNotFoundException
  • FileInputStream(File)
文件字节输出流的构造方法 :
  • FileOutputStream(“文件名称”) 如果文件不存在则新建文件,如果文件存在则覆盖文件内容
  • FileOutputStream(String name文件名称, boolean append是否采用追加方式)
FileReader FileWriter 类似
FileInputStream FileOutputStream 两个类属于结点流,第一个类的源端和第二个类的目的端都是磁盘文件,它们的构造方法允许通过文件的路径名来构造相应的流。
如:
FileInputStream infile = new FileInputStream("myfile.dat");
FileOutputStream outfile = new FileOutputStream("results.dat");
要注意的是,构造 FileInputStream, 对应的文件必须存在并且是可读的,而构造 FileOutputStream 时,如输出文件已存在,则必须是可覆盖的
d 盘上的 TestFile.java 拷贝到 e 盘,并命名为 dd.txt
try(
	InputStream is = new FileInputStream("d:/TestFile.java");
	OutputStream os = new FileOutputStream("e:\\dd.txt");)
	{
		byte[] buffer = new byte[8192];
		int len = is.read(buffer);
		while (len > 0) {
			os.write(buffer, 0, len);
			len = is.read(buffer);
		}
	}catch(
	IOException e)
	{
		e.printStackTrace();
}

// 构造输出文件流时可以使用两种不同的方式
OutputStream os = new FileOutputStream("e:\\dd.txt");
// 如果文件不存在则自动创建;如 果文件存在则进行覆盖
OutputStream os=new FileOutputStream("e:\\dd.txt",true),
// 这里的boolean类型参数 表示是否采用追加的方式写入文件

内存数组节点

如果文本则使用 char[] ,如果二进制则使用 byte[]
构造器方法
  • CharArrayReader(char[] buf)其中char[]就是数据的来源,也就是说Reader就是从char[]中读取数
  • CharArrayRead(char[] buf, int offset, int length)
CharArrayWriter 用于实现向一个字符数组中写入数据,这个数组可以自动调整大小
ByteArrayInputStream ByteArrayOutputStream CharArrayReader 以及 CharArrayWriter 类似,支持操作的内容不同而已,操作 byte[] char[]

内存字串流

StringReader 用于从一个字串 String 中读取数据
String str = "亚洲说:‘我爱小黑’";
	StringReader sr = new StringReader(str);
	int cc;while((cc=sr.read())!=-1)
		System.out.print((char)cc);
	sr.close();
StringWriter 用于给一个 StringBuffer 中写入数据,实现一个可边长的字串
Scanner sc=new Scanner(System.in);try(
	StringWriter sw = new StringWriter();
	Writer fw = new FileWriter("c:/console.txt"))
	{
		String temp = sc.nextLine();
		while (!temp.equals("quit")) {
			if (temp != null && temp.trim().length() > 0)
				sw.write(temp + "\n");
			temp = sc.nextLine();
		}
		fw.write(sw.toString());
	}

总结

  • 读写文件使用节点流FileInputStream/FileOutputStreamFileReader/FileWriter,如果操作文本 文件,建议使用FileReader/FileWriter,如果操作二进制文件建议使用 FileInputStream/FileOutputStream
  • 需要建立缓冲区(建立临时文件的方式效率低),可以考虑使用内存节点,例如 CharArrayReader/CharArrayWriterStringReader/StringWriterByteArrayInputStream/ByteArrayOutputStream
  • 如果需要一个二进制缓冲区可以使用ByteArrayInputStream/ByteArrayOutputStream,如果需要 一个字符缓存可以使用CharArrayReader/CharArrayWriterStringReader/StringWriter
  • 如果数据量不是特别大使用CharArrayReader/CharArrayWriter更为方便,如果数据量大而且可能 需要直接操作缓冲区则使用StringReader/StringWriter
  • StringWriter中提供了方法getBuffer():StringBuffer

过滤流类型

过滤流就是在节点流的基础上附加功能

 

处理类型
字符流
字节流
缓存
BufferedReader BufferedWriter
BufferedInputStream
BufferedOutputStream
过滤处理
FilterReader FilterWriter
FilterInputStream
FilterOutputStream
桥接处理
InputStreamReader
OutputStreamWriter
对象序列化
处理
ObjectInputStream
ObjectOutputStream
数据转换
DataInputStream
DataOutputStream
行数统计
LineNumberReader
LineNumberInputStream
回滚处理
PushbackReader
PushbackInputStream
打印功能
PrintWriter
PrintStream

过滤流

就是 decorate 模式中的抽象装饰角色
FilterInputStream/FilterOutputStream FilterReader/FilterWriter
所谓的过滤流实际上就是类似上面的加密处理,在输入之后(后置处理,被装饰对象先执行)或者输出之前(前置处理,先处理然后被装饰对象执行)进行一下额外的处理,最终实际操作是调用被装饰对象 的方法完成工作,依靠这种装饰模式实现在节点流的基础上附加额外功能 . 当然也允许多个过滤流嵌套从 而达到功能累加的目的
FilterInputStream 实际上就是一个装饰抽象角色
自定义流实现循环 13 加密 :
      读取数据不变 :FileReader---BufferedReader
      写出数据自定义过滤流 SecurityWriter(FilterWriter)
public class SecurityWriter extends FilterWriter {
		protected SecurityWriter(Writer out) {
			super(out);
		}

		public void write(int c) throws IOException {
			if (c >= 'a' && c <= 'z') {
				c = (c - 'a' + 13) % 26 + 'a';
			} else if (c >= 'A' && c <= 'Z') {
				c = (c - 'A' + 13) % 26 + 'A';
			}
			super.write(c);
		}
	}
	public class SecurityReader extends FilterReader {
		protected SecurityReader(Reader in) {
			super(in);
		}

		public int read() throws IOException {
			int c = super.read();
			if (c >= 'a' && c <= 'z') {
				c = (c - 'a' + 13) % 26 + 'a';
			} else if (c >= 'A' && c <= 'Z') {
				c = (c - 'A' + 13) % 26 + 'A';
			}
			return c;
		}
	}

桥接转换流

InputStreamReader OutputStreamWriter java.io 包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介:从字节输入流读入字节,并按编码规范转换为字符;往字节输出流写字符时 先将字符按编码规范转换为字节。使用这两者进行字符处理时,在构造方法中应指定一定的平台规范, 以便把以字节方式表示的流转换为特定平台上的字符表示。
转换流可以在构造时指定其编码字符集
InputStreamReader 用于将一个 InputStream 类型的输入流自动转换为 Reader 字符流
OutputStreamWriter 用于将一个 Writer 字符输出流转换为 OutputStream 字节输出流

InputStreamReader构造器

  • InputStreamReader(InputStream)
  • InputStreamReader(InputStream, String)
  • InputStreamReader(InputStream, Charset)
  • InputStreamReader(InputStream, CharsetDecorder)
缓冲流
缓冲流是套接在响应的节点流之上,对续写的数据提供缓冲的功能,提高读写的效率,同时增加了一些新方法
以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬盘。 如果读写的频率比 较高的时候,其性能表现不佳。为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。
InputStream is = new FileInputStream("d:\\FileTest.java");
	long start = System.currentTimeMillis();
	int con = is.read();while(con!=-1)
	{
		System.out.write(con);
		con = is.read();
	}
	long end = System.currentTimeMillis();
	is.close();
	System.out.println("统计时间为:"+(end-start)+"ms");

构造方法

  • BufferedReader(Reader)不定义缓存大小,默认8192
  • BufferedReader(Reader in, int size)size为自定义缓冲区的大小
  • BufferedWriter(Writer)
  • BufferedWriter(Writer out, int size)size为自定义缓冲区的大小
  • BufferedInputStream(InputStream)
  • BufferedInputStream(InputStream in, int size)size为自定义缓冲区的大小
  • BufferedOutputStream(OutputStream)
  • BufferedOutputStream(OuputStream out, int size)size为自定义缓冲区的大小

缓冲输入流的方法

BuffedReader 提供了一个方法 readLine():String ,但是 BufferedInputStream 中并没有这个
  • BufferedReader提供了readLine方法用于读取一行字符串,以\r\n分割(换行符)
  1. 如果读取内容为null,则表示读取到了流的末尾
  2. readLine方法会自动剔除本行内容末尾的换行符
  • BufferedWriter提供了newLine方法用于写入一个行分隔符
对于输出的缓冲流,写入的数据会先在内存中缓存,使用 flush 方法会使内存中的数据立即写出

数据流

DataInputStream DataOutputStream 两个类创建的对象分别被称为数据输入流和数据输出流。这是很有用的两个流,它们允许程序按与机器无关的风格读写 Java 数据。所以比较适合于网络上的数据传 输。这两个流也是过滤器流,常以其它流如 InputStream OutputStream 作为它们的输入或输出
DataInputStram DataOutputStream 分别继承自 InputStream OuputStream ,属于过滤流,需要分别套接在 InputStream OutputStream 类型的节点流上
  • 只有字节流,没有对应的字符流
DataInputStream DataOutputStream 提供了可以存取与机器无关的 Java 原始类型数据的方法
DataInputSteram DataOutputStream 构造方法为
  • DataInputStream(InputStream)
  • DataOutputStream(OutputStream)

打印流

PrintStream PrintWriter 都属于输出流,分别针对字节和字符
PrintWriter PrintStream 都提供了重载的 print println 方法用于输出多种类型数据
print(Object):void
  • 输出引用类型,实际上是调用对象的toString方法转换为String进行输出
public void println(Object x) {
		String s = String.valueOf(x);//调用String类中的静态方法将object类型的 数据转换为字符串
		synchronized (this) {
			print(s);
			newLine();//print('\n')
		}
	}
//String中的valueOf方法的定义
	public static String valueOf(Object obj) {
		return (obj == null) ? "null" : obj.toString();//如果输出对象非空,则调用对象的吗toString方法
	}
println 表示输出后自动换行
  • PrintWriterPrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
  • PrintWriterPrintStream有自动的flush功能 textOut.flushBuffer();
PrintWriter(Writer)
PrintWriter(Writer out, boolean autoFlush) 自动刷新 ----println
PrintWriter(OutputStream out) //参数是一个字节流,但是不需要通过桥接处理 PrintWriter(OutputStream out, boolean autoFlush) 

PrintStream(OutputStream)
 PrintStream(OutputStream out, boolean autoFlush)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值