Java文本数据IO操作-字符流)

文本数据IO操作

流的拓展:字符流

java将流按照读写单位划分为字节流和字符流

我们前面学的文件流、缓冲流、对象流

字符流是为了方便我们读写文本

字符流介绍:
java.io.Reader
java.io.Writer
上述两个类是所以字符流的超类,规定了所有字符流都必须具备的读写字符的相关方法

字符流是以字符(char)为单位读写数据的
一次处理一个unicode
字符流的底层仍然是基本的字节流,只是字符与字节的转换,字符流自行完成
字符流封装了字符的编码解码算法

字符流仅仅用于文本数据IO操作

下面为常见文本流

一、转换流(高级流)

java.io.InputStreamReader
java.io.OutputStreamWriter

转换流是一对字符流,同时他们也是高级流,而且是唯一能连接字节流的字符流(相当于转换器)

在实际开发时,我们通常不会直接操作这两个流
但是在读写文本数据时,流连接中,他们是重要的一环
负责衔接其他字符高级流与字节流

在使用转换流时,要注意需要先创建低级流,转换流是高级流,依附于低级流实现

步骤:

  1. 创建低级流(为流的管道,是高级流的依附条件,一般为文件流)
  2. 创建高级流(这里传入参数为低级流对象和字符集编码格式)
  3. 写出:write(字符串)

​ 读入:可单字符或字符数组读入

  1. 关闭高级流

注意事项:

  1. 在写出操作中创建转换流时,注意在创建转换流时设置字符集
    转换流在创建时通常会传入第二个参数,这个参数用来指定字符集
    这样一来,通过当前流写出的文本数据都会按照该字符集转换为字节后写出
  2. 转换流是知道编码规则的,所以他会按需读取,能把字符按中英文分开成单个字符
    所以他可以单独读一个字符,会自动按中英文字节分开为一个字符读取

使用转换流写出文本数据:

package io;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OSDemo {
	public static void main(String[] args) throws IOException {
		//创建低级流(文件流)
		FileOutputStream fos = new FileOutputStream("./osw.txt");
		//创建高级流(字符流:转换流)
		//注意:设置字符集在创建转换流时设置
		/*
		 * 转换流在创建时通常会传入第二个参数,这个参数用来指定字符集
		 * 这样一来,通过当前流写出的文本数据都会按照该字符集转换为字节后写出
		 */
		OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
		//转换流提供了转换方法,可以直接写入字符串,无需我们字节转换
		osw.write("我李淳罡要甚天道?一剑足矣!");
		osw.write("生平仅有三尺剑,有蛟龙处杀蛟龙");
		
		System.out.println("写出完毕!");
		osw.close();
	}
}

使用转换流读入文本数据:

package io;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;

public class ISRDemo {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("./osw.txt");
		InputStreamReader isr = new InputStreamReader(fis,"utf-8");
		//注意:转换流是知道编码规则的,所以他会按需读取,
		//可以单独读一个字符,会自动按中英文字节分开为一个字符读取
		//单字符读取
//		int d = -1;
//		while((d = isr.read())!=-1){
//			System.out.print((char)d);
//		}
		//字符数组读取方法
		char[] data = new char[1024*10];
		int len = -1;
		String str = "";
		while((len=isr.read(data))!=-1){
            //将字符数组写在一个字符串里面
			str = str.concat(new String(data,0,len));
		}
		System.out.println(str);
		isr.close();
	}
}

二、缓冲字符流(高级流)PW

缓冲字符流

java.io.BufferedWriter
java.io.BufferedReader
缓冲流是块读写文本数据,提高读写效率,并且可以按行读写字符串

1、缓冲字符输出流

java.io.BufferedWriter (实现PW需要传入这个的对象)

java.io.PrintWriter (一般用这个 pw)

具有自动 行刷新 的缓冲字符输出流
PrintWriter的构造方法传入参数为流和是否开启自动行刷新功能,默认关闭
根据具体需求,看是否需要打开该功能

内部总是连接BufferedWriter作为其缓冲加速操作

注意:这个高级流不用自己创建低级流,因为在这个高级流底层为我们实现了流连接
但是我们根据需求,如果要用其他的流连接线路,我们需要自行完成流连接
看着好像是低级流,其实是因为在这个类的构造方法中已经实现了

查看该类源码我们发现,该类构造方法内部会自动进行流连接操作,
分别连接缓冲字符流、转换流、文件流

/* Private constructor */
    private PrintWriter(Charset charset, File file)
        throws FileNotFoundException
    {
        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)),
             false);
    }

步骤:

  1. 创建pw对象,传入路径和编码格式(也可自行创建流连接)
  2. 写出数据(print,和输出到控制台的语句相似)
  3. 关闭pw
package io;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

public class PWDemo1 {
	public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
		/*
		 * 向pw.txt文件中写出字符串
		 */
		PrintWriter pw = new PrintWriter("./pw.txt","utf-8");
		pw.println("西楚曹长卿,落子太安城");
		pw.println("唯我大楚:");
		pw.print("宁在雨中高歌死,");
		pw.print("不去寄人篱下活!");
		System.out.println("写出完毕!");
		pw.close();
	}
}

自行完成流连接,使用PW写出文本数据

package io;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

public class PWDemo2 {
	public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
		//基础的低级流,文件流
        FileOutputStream fos = new FileOutputStream("pw2.txt");
		//转换流,这里需要设置编码格式
		OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
        //缓冲字符流
		BufferedWriter bw = new BufferedWriter(osw);
		PrintWriter pw = new PrintWriter(bw);
		pw.print("生而为人且善良,");
		pw.print("长亦成芒");
		System.out.println("写出完毕!");
		pw.close();
	}
}

练习:实现简易记事本工具

程序启动后,要求输入文件名,然后对文件写入内容
将后续在控制台输入的每行字符串都按行写入到该文件中
当单独输入了exit时,程序退出

要求:自行使用流连接创建pw

package io;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;

public class PWdemo3 {
	public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException {
		Scanner input = new Scanner(System.in);
		//接收文件名
		System.out.print("请输入文件名:");
		String path = input.nextLine()+".txt";
		//创建低级流,文件流,接收文件路径
		FileOutputStream fos= new FileOutputStream(path);
		//创建高级流,转换流,转换字节流为字符流,接收文件编码格式
		OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
		//创建缓冲字符流
		BufferedWriter bw = new BufferedWriter(osw);
		PrintWriter pw = new PrintWriter(bw,true);
		//提示用户记事本已经打开,提示输入
		System.out.println("请输入内容:(单行输出exit退出记事本)");
		while(true){
			//创建字符串容器,接收控制台输入的值
			String str = input.nextLine();
			if("exit".equals(str)){
				break;
			}
			pw.println(str);
			//如果想要写一句存一句,可以调用flush方法
			//清空缓冲区,写一句存一句
			//pw.flush();
		}
		//写出完毕
		System.out.println("写出完毕!");
		//关闭pw,关闭时会自动调用缓冲流中的flush方法清空缓冲区,所以要记得写关闭
		pw.close();
	}
}

PW的自动行刷新功能

PrintWriter的构造方法,还可以再传入一个boolean值的参数,传入true表示打开了自动行刷新功能

会每输入一行,就存入一行,类似于每输入一行就调用一次flush清空缓冲区

PrintWriter pw = new PrintWriter(bw,true);

2、缓冲字符输入流

java.io.BufferedReader

块读取文本数据,并且可以按行读取字符串

其读取方法含有行读取
String readLine()
该方法会:连续读取若干字符,直到读取到换行符为止,将换行符之前的字符组成一个字符串返回
如果返回值为null,表示流读取到文件末尾了

package io;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class BRDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 将当前源代码内容输出到控制台
		 */
		FileInputStream fis= new FileInputStream("./src/io/BRDemo.java");
		InputStreamReader isr = new InputStreamReader(fis);
		BufferedReader br = new BufferedReader(isr);
        //String readLine(),读取行文件方法
		String line = null;
		while((line = br.readLine())!=null){
			System.out.println(line);
		}
		br.close();
	}
}

IO操作主要的流表格(java中io流的体系)

字节流字符流
低级流InputStreamOutputStreamReaderWriter
FileInputStream(负责从文件中读取字节)FileOutputStream(负责从文件中写入字节)
高级流BufferedInputStream(块读字节,加快读取效率)BufferedOutputStream(块写字节,加快写入效率)InputStreamReader(衔接字符流与字节流,将字节转换为字符)OutputStreamWriter(衔接字节流与字符流,将字符转换为字节)
ObjectInputStream(对象反序列化)ObjectOutputStream(对象序列化)BufferedReader(块读文本数据,按行读取字符串)BufferedWriter/PrintWriter(块写文本数据,按行写入)

io流和raf有什么区别

raf更灵活,有指针,想读文件哪里读哪里
io流适用于网络数据传输

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值