java继承:IO流---字符流

概述

当使用字节流读取文本文件时,读出来的数据是一个个字节,不方便查看和操作,并且一个字符可能会由多个字节组成。例如,中文字符。JavaAPI中提供了字符流,可以用字符的形式,读写数据,专门用于处理文本数据。

java.io.Reader是所有字符输入流的抽象父类型
java.io.Writer是所有字符输出流的抽象父类型。

Reader中最核心的三个read方法

//每次读取一个字符,返回这个字符的编码值
public int read() throws IOException {    
	char cb[] = new char[1];    
	if (read(cb, 0, 1) == -1)        
		return -1;    
	else        
		return cb[0];
}

//每次读取多个字符,并存放到指定字符数组中,返回值是本次读取到的字符个数
public int read(char cbuf[]) throws IOException {    
	return read(cbuf, 0, cbuf.length);
}

//每次读取多个字符,并存放到指定字符数组中,返回值是本次读取到的字符个数
//同时可以指定从数组的什么位置开始存放,以及在数组中最多存放多个字符
abstract public int read(char cbuf[], int off, int len) throws IOException;

Wireter中最常用的write方法

//写出去一个字符,注意字符可以使用int值来表示
public void write(int c) throws IOException {    
	synchronized (lock) {    
    if (writeBuffer == null){      
          writeBuffer = new char[WRITE_BUFFER_SIZE];   
    }        
    writeBuffer[0] = (char) c;    
    write(writeBuffer, 0, 1);   
 	}
}

//写出去数组中的多个字符
public void write(char cbuf[]) throws IOException {    
	write(cbuf, 0, cbuf.length);
}

//写出去数组中的多个字符
//可以指定从数组的什么位置开始写,以及多少个字符
abstract public void write(char cbuf[], int off, int len) throws IOException;

//写出去一个字符串
public void write(String str) throws IOException {    
	write(str, 0, str.length());
}

//写出去一个字符串
//可以指定从字符串的什么位置开始写,以及多少个字符
public void write(String str, int off, int len) throws IOException {    
	synchronized (lock) {        
	char cbuf[];        
	if (len <= WRITE_BUFFER_SIZE) {            
		if (writeBuffer == null) {                
			writeBuffer = new char[WRITE_BUFFER_SIZE];           
		}            
		cbuf = writeBuffer;       
		} else {            
			cbuf = new char[len];       
		}        
		str.getChars(off, (off + len), cbuf, 0);        
		write(cbuf, 0, len);   
	}
}

可以看到字符流中的读和写的方法,与字节流中的读和写方法类似

字符数组

使用字符流,从字符数组中读取数据,以及向字符数组中写数据。
java.io.CharArrayReader 负责从字符数组中读取数据。
java.io.CharArrayWriter 负责把数据写入到字符数组中。

和字节数组一样使用

import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;

public class Test01 {
	public static void main(String[] args) {
		//1、声明流
		Reader in = null;
		Writer out = null;
		
		char[]	arr = "hello 中国".toCharArray();
		//2、创建流
		
		in = new CharArrayReader(arr);
		out = new CharArrayWriter();
		
		//3、使用流
		int len = -1;
		char[] cbuf = new char[1024];

		try {
			len = in.read(cbuf);
			out.write(cbuf,0,len);
			out.flush();
			
			//CharArrayWriter中的toCharArray方法,可以将写入到out对象中的数据返回
			char[] charArray = ((CharArrayWriter)out).toCharArray();
			//使用Arrays工具类中的toString方法接收数组并输出
			System.out.println(Arrays.toString(charArray));
			
			System.out.println();
			//普通for循环输出也可以
			for(int i = 0;i<charArray.length; i++) {
				System.out.print(charArray[i] + " ");
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			//4、关闭流
			if(in!=null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

在这里插入图片描述

管道字符流

使用字符流,可以从管道中读取数据,以及向管道中写数据。

java.io.PipedReader负责从管道中读取数据
java.io.PipedWriter负责将数据写入到管道中

使用起来好管道字节流一样,一般可以在一个线程中,使用管道输出流,将数据写入到管道中,在另一个线程中,读取管道中的数据。

在这里插入图片描述

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;

public class Test02 {
	public static void main(String[] args) {
		PipedReader in = null;
		PipedWriter out = null;
		
		in = new PipedReader();
		out = new PipedWriter();
		
		try {
			//管道对接
			in.connect(out);
			
			Thread t1 = new writerThread(out);
			Thread t2 = new readerThread(in);
			
			//启动线程
			t1.start();
			t2.start();
			
			t1.join();
			t2.join();
			
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}

//将数据写入到管道中
class writerThread extends Thread{
	private Writer out;

	//构造器:用于创建线程对象后进行创参
	public writerThread(Writer out) {
		this.out = out;
	}

	@Override
	public void run() {
		//将字符转换为字节存放到字节数组中
		char[] arr = "hello world java".toCharArray(); //这个是要输入的内容
		
			try {
				for(int i = 0; i<arr.length; i++) {
					out.write(arr[i]);
					out.flush();
					Thread.sleep(1000); //让线程每次写一个字符,休息1秒
				}
			} catch (IOException | InterruptedException e) {
				e.printStackTrace();
			} finally {
				if(out != null) {
					try {
						out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
	}
	
}

//从管道中读取数据并且输出
class readerThread extends Thread{
	private Reader in;

	public readerThread(Reader in) {
		this.in = in;
	}

	@Override
	public void run() {
		int len = -1;
		try {
			while((len = in.read())!=-1) {
				//第一种输出方式:输出字节
//				System.out.print(len);
				//第二种输出方式:输出字符
				System.out.write(len);
				
				//别忘了刷新
				System.out.flush();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(in!= null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

结果嘛,就是每隔一秒输出一个字符

文件字符流

使用字符流,可以从文件中读取数据,以及向文件中写数据。
java.io.FileReader,负责从文件中读取数据
java.io.FileWriter,负责把数据写入到文件中

这俩个其实是JavaAPI中封装好的便捷类,里面使用了文件字节流来实现的,方便我们操作字符文件,操作起来和文件字节流相似

代码演示:
a.txt文件的路径如下:src/Test/test2/files/a.txt,内容为蓝瘦香菇 爱了爱了
将a.txt中的内容输出到同级文件b.txt中

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class Test03 {
	
	public static void main(String[] args) {
		
		Reader in = null;
		Writer out = null;
		
		try {
			String fileName = "src/Test/test2/files/a.txt";
			String fileNameCopy = "src/Test/test2/files/b.txt";
			in = new FileReader(fileName);
			out = new FileWriter(fileNameCopy);
			
			int len = -1;
			char[] cbuf = new char[1024];
			while((len = in.read(cbuf))!=-1) {
				out.write(cbuf,0,len);
				out.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(out!=null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

结果如下:
在这里插入图片描述

其他

与非节点流搭配使用了,具体看非节点流章节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值