IO流详解(一)字符流

java中的流对象分为两种:字节流和字符流。 其实严格来说,流只有字节流一种,因为任何数据都是二进制字节,只不过字符串文本操作是很常见的需求,所以jdk就帮我们封装好了一些操作字符流的对象reader和writer他们的底层都是字节流。这一小结主要讲的是字符流,流对象中以reader和writer结尾的都是字符流。

一:FileWriter

需求:将一些文字存储到硬盘一个文件中。
分析:如果要操作文字数据,优先考虑字符流,而且要将文字数据从内存写到硬盘上,要使用字符输出流,Writer。硬盘的数据基本体现是文件。 所以就找到了FileWriter
public class FileWriterDemo {
	
	private static final String LINE_SEPARATOR = System.getProperty("line.separator");
	
	public static void main(String[] args) throws IOException {
		
		/**
		 * 创建一个可以往文件中写字符数据的字符输出流对象。
		 * 既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(用于存储数据的目的地)。
		 * 
		 * 如果文件不存在,则会自动创建。
		 * 如果文件存在,则会被覆盖。
		 * 
		 * 如果构造函数中加入true,可以实现对文件进行续写!
		 */
		FileWriter fw = new FileWriter("demo.txt", true);
		
		/*
		 * 调用Writer对象中的write(string)方法,写入数据。 
		 * 
		 * 其实数据写入到临时存储缓冲区中,并不是写入到文件。这时候应该怎么办,我们看一看flash方法
		 * 
		 * "\r\n":windows下换行
		 * "\n":在jdk1.8上测试可以换行
		 * 如果想支持的更好,那么我们就那系统为我们提供的
		 */
		fw.write("Hello io" + LINE_SEPARATOR + "2017年6月11日18:27:39");
		
		/**
		 * 进行刷新,将数据直接写到目的地中。
		 * flash:刷新该流的缓冲。如果该流已保存缓冲区中各种 write() 方法的所有字符,则立即将它们写入预期目标。
		 */
		fw.flush();
		
		/*
		 * 关闭此流,但会先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。关闭以前关闭的流无效。 
		 */
		fw.close();
	}
	
}

二:FileReader

需求:读取文本文件。将读取到的文件打印到控制台。 既然是读取文本文件那么就用字符流Reader。硬盘中的文件是以文本体现所以就用到了FileReader
版本一:一个一个读取
public class FileReaderDemo {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {

		/*
		 * 创建读取字符数据的流对象。
		 * 在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的。 
		 * 
		 * 用一个读取流关联一个已存在文件。 
		 */
		FileReader fr = new FileReader("demo.txt");
		
		/**
		 * 用Reader中的read方法读取字符,只能读取单个字符。
		 * 返回:作为ascll码,如果已到达流的末尾,则返回 -1 
		 */
		int ch = fr.read();
		System.out.println( (char)ch );
		
		int ch1 = fr.read();
		System.out.println( ch1 );
		
		int ch2 = fr.read();
		System.out.println( ch2 );

		fr.close();
	}

}

版本二:一次一个的读取明显太麻烦了,现在我们使用循环来读取
public class FileReaderDemo {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {

		/*
		 * 创建读取字符数据的流对象。
		 * 在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的。 
		 * 
		 * 用一个读取流关联一个已存在文件。 
		 */
		FileReader fr = new FileReader("demo.txt");
		
		/**
		 * 有了下面的教程,我们可以写一个循环来读取
		 */
		int ch = 0;
		
		while ( (ch = fr.read()) != -1){
			System.out.print((char)ch);
		}
		
		
		/**
		 * 用Reader中的read方法读取字符,只能读取单个字符。
		 * 返回:作为ascll码,如果已到达流的末尾,则返回 -1 
		 */
/*		int ch = fr.read();
		System.out.println( (char)ch );
		
		int ch1 = fr.read();
		System.out.println( ch1 );
		
		int ch2 = fr.read();
		System.out.println( ch2 );
*/		
		fr.close();
	}

}

三:FileReader和FileWriter流组合使用

需求:将C盘中的一个文本文件复制到D盘
public class CopyTextTest {
	
	public static void main(String[] args) throws IOException {
		
		FileReader fr = new FileReader("d://io.txt");
		FileWriter fw = new FileWriter("e://a.txt");
		
		char[] buf = new char[1024];	//这个就是缓冲区
		int len = 0;
		
		while ( (len = fr.read(buf)) != -1) {
			fw.write(buf, 0, len);
		}
		
		fw.close();
		fr.close();
	}
	
}

四:Buffer缓冲区

我们通过demo就会发现。我们在读数据的时候是定义了一个1024位的字节数组来当做缓冲区,为什么要用缓冲区。举个例子缓冲区就好比我们去超市推得购物车,超市的商品可以看做是源文件,收银台就好比目地文件。 我们能拿东西的数量是有限的,如果我们一点一点的拿就显得很麻烦,这时候我们如果推一个购物车。这样的效率明显提高了。 jdk很显然知道我们有这样的需求,早就为我们考虑到了。 这时候就引入了BufferReader和BufferWriter
BufferReader:
public class BufferedReaderDemo {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {

		FileReader fr = new FileReader("buf.txt");
		BufferedReader bufr = new BufferedReader(fr);
		
		String line = null;
		
		/**
		 * 引入了缓冲区之后,缓冲区对象一次性就从磁盘中抓取‘一些数据’,放入缓冲中。
		 * 那么我们以后我们要读取的话,就可以直接从缓冲区中获取数据,而不是从磁盘中读取。
		 * 这样就降低了io的消耗。
		 * 
		 * 既然我们获取了一些数据就可以使用readLine一次读一行,这是缓冲区为我们封装的方法
		 * 
		 * readLine():使用了读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记。
		 * 将标记前的缓存数据变成字符串返回。
		 */
		while ( (line = bufr.readLine()) != null) {
			System.out.println(line);
		}
		
		bufr.close();
	}

}
BufferWriter:
public class BufferedWriterDemo {

	private static final String LINE_SEPARATOR = System.getProperty("line.separator");

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {

		FileWriter fw = new FileWriter("buf.txt");
		
		/**
		 * 为了提高写入的效率。使用了字符流的缓冲区。
		 * 
		 * 创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联
		 */
		BufferedWriter bw = new BufferedWriter(fw);

		/**
		 * 使用缓冲区的写入方法将数据先写入到缓冲区中。
		 */
		bw.write("wirter" + LINE_SEPARATOR + "reader");
		bw.write("Tig");
		bw.newLine();	//换行
		bw.write("2017年6月11日21:46:15");
		
		//使用缓冲区的刷新方法将数据刷目的地中。
		bw.flush();
		
		//关闭缓冲区。其实关闭的就是被缓冲的fw流对象。
		bw.close();
		
		
		/**
		 * 所以当你关闭了缓冲区,fw也就默认关闭,因为缓冲区只是封装了数组
		 * 提高流中数据操作效率的,没有调用流资源。
		 * 
		 * 所以别认为我关闭了bw没有关闭fw。我们就可以写东西了。
		 * fw.write("hehe");
		 * fw.close();
		 */
	}

}

五:BufferReader和BufferWriter组合练习

需求:从d盘中读取一个文件到e盘,加入缓冲
public class CopyTextByBufTest {
	
	public static void main(String[] args) throws IOException {
		
		FileReader fr = new FileReader("d://io.txt");
		FileWriter fw = new FileWriter("e://a.txt");
		
		BufferedReader br = new BufferedReader(fr);
		BufferedWriter bw = new BufferedWriter(fw);
		
		String line = null;
		while ( (line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();	//因为我们一行一行读取的时候是没有读取换行符,所以这地方要换行
			bw.flush();		
		}
		
		bw.close();
		br.close();
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值