Java IO流(续)

第一章 字节缓冲流

1.1字节缓冲区流的概述和使用

1.1.1 字节缓冲流的作用是?

字节流一次读写一个数组的速度比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓冲区流

字节缓冲流 :

	BufferedOutputStream:字节缓冲输出流
	BufferedInputStream:字节缓冲输入流

1.1.2 为什么字节缓冲流的构造方法需要传入一个OutputStream

字节缓冲区流仅仅提供缓冲区,而真正的底层的读写数据还得需要基本的流对象进行操作。

1.2 字节流四种方式复制AVI并测试效率

1.2.1 方法摘要
public static long currentTimeMillis():返回以毫秒为单位的当前时间。

第二章 转换流

2.1 转换流出现的原因

2.1.1字节流读数据可能出现问题
字节流一次读取一个字节的方式读取带有汉字的文件是有问题的,因为你读取到一个字节后就转为字符在控制台输出了,而汉字是由2个字节组成的,所以这里会出问题。

	文件复制的时候,字节流读取一个字节,写入一个字节,这个没有出现问题,是因为最终底层会根据字节做拼接,得到汉字。

	汉字存储的规则:
		左边的字节数据肯定是负数,右边的字节数据可能是负数,也可能是正数,大部分情况下是负数。
2.1.2 案例代码
public class FileInputStreamDemo {
	public static void main(String[] args) throws IOException {
		//基本字节流一次读取一个字节
//		FileInputStream fis = new FileInputStream("a.txt");
//		
//		int by;
//		while((by=fis.read())!=-1) {
//			System.out.print((char)by);
//		}
//		
//		fis.close();
		//通过一个字符串得到一个字节数组
		//String s = "hello";
		//[104, 101, 108, 108, 111]
		String s = "你好";
		//[-60, -29, -70, -61],-60和-29表示的是你,-70和-61表示的是好
		byte[] bys = s.getBytes();
		System.out.println(Arrays.toString(bys));
	}
}

2.1.3 转换流的组成部分
转换流 = 字节流 + 编码表

	这句话怎么理解 ? 往下看, 先说编码表

2.2 编码表概述和常见编码表

2.2.1 什么是编码表?
编码表:
由字符及其对应的数据组成的一张表
ASCII:
‘a’ 97
‘A’ 65
‘0’ 48
常见的编码表:
ASCII : 美国标准信息交换码, 用一个字节的7位表示数据
ISO-8859-1 : 欧洲码表, 用一个字节的8位表示数据, 兼容ASCII
GB2312 : 中文码表的升级版, 融合了更多的中文文字符号, 兼容ASCII
UTF-8 : 是一种可变长度的字符编码, 用1-3个字节表示数据, 又称为万国码, 兼容ASCII。用在网页上可以统一页面中的中文简体繁体和其他语言的显示.

后面是学习中常用的编码表有GBK和UTF-8。最常用的是UTF-8。
2.2.2 乱码问题
针对同一个数据, 采用的编码和解码不一致导致

你好,我们用GBK和UTF来编码和解码是没有问题的,那什么时候会有问题呢?
针对同一个数据, 采用的编码和解码不一致导致,比如我采用的GBK进行的编码,而解码却常用的是UTF-8。为什么呢?
因为汉字在不同的编码表中所存储的位置是不一样的。

2.3 String类中的编码和解码问题

2.3.1 方法摘要&编码和解码
• 编码
把看得懂的变成看不懂的
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
• 解码
把看不懂的变成看得懂的
public String(byte[] bytes, String charsetName)
通过使用指定的 charset解码指定的 byte 数组,构造一个新的 String。

重点强调 :  编码和解码的方式需要一致

2.3.2 案例代码

public class StringDemo {
	public static void main(String[] args) throws UnsupportedEncodingException {
		//定义一个字符串
		String s = "你好";
		
		//编码
		//byte[] bys = s.getBytes();//使用平台的默认字符集将此 String 编码为 byte 序列
		//默认编码是GBK
		//[-60, -29, -70, -61]
		//byte[] bys = s.getBytes("GBK"); //指定编码GBK
		//[-60, -29, -70, -61]
		byte[] bys = s.getBytes("UTF-8"); //指定编码UTF-8
		//[-28, -67, -96, -27, -91, -67]
		System.out.println(Arrays.toString(bys));
		
		//解码
		//String ss = new String(bys); //通过使用平台的默认字符集解码指定的 byte 数组
//		String ss = new String(bys,"GBK");//指定编码GBK
		String ss = new String(bys,"UTF-8");//指定编码UTF-8
		System.out.println(ss);
	}
}

2.4 转换流中的编码和解码问题

2.4.1 转换流指的是?
转换流其实就是一个字符流。
转换流 = 字节流 + 编码表
2.4.2 转换流的构造方法
OutputStreamWriter 字符输出流
public OutputStreamWriter(OutputStream out)
根据默认编码把字节流的数据转换为字符流
public OutputStreamWriter(OutputStream out,String charsetName)
根据指定编码把字节流数据转换为字符流

InputStreamReader 字符输入流
public InputStreamReader(InputStream in)
用默认的编码读数据
public InputStreamReader(InputStream in,String charsetName)

2.5 OutputStreamWriter写数据的5种方式

2.5.1 方法摘要

  • OutputStreamWriter写数据方法
    • public void write(int c):写一个字符
    • public void write(char[] cbuf):写一个字符数组
    • public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
    • public void write(String str):写一个字符串
    • public void write(String str,int off,int len):写一个字符串的一部分

2.6 InputStreamReader读数据的2种方式
2.6.1 方法摘要
* public int read():一次读取一个字符

  • public int read(char[] cbuf):一次读取一个字符数组

第三章 字符流

3.1 字符流的练习之复制Java文件

3.1.1 案例代码

/*
 * 把当前项目目录下的StringDemo.java内容复制到当前项目目录下的Copy.java中
 * 
 * 数据源:
 * 		StringDemo.java---读数据---字符流---InputStreamReader
 * 目的地:
 * 		Copy.java---写数据---字符流---OutputStreamWriter
 */
public class CopyJavaTest {
	public static void main(String[] args) throws IOException {
		//封装数据源
		InputStreamReader isr = new InputStreamReader(new FileInputStream("StringDemo.java"));
		//封装目的地
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Copy.java"));
	
		//读写数据
		//方式1:一次读写一个字符
//		int ch;
//		while((ch=isr.read())!=-1) {
//			osw.write(ch);
//		}
		
		//方式2:一次读写一个字符数组
		char[] chs = new char[1024];
		int len;
		while((len=isr.read(chs))!=-1) {
			osw.write(chs, 0, len);
		}
		
		//释放资源
		osw.close();
		isr.close();
	}
}

3.2 字符流的练习之复制Java文件改进版

3.2.1 改进原因
转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类。
FileWriter
FileReader

3.2.2 案例代码

public class CopyJavaTest2 {
	public static void main(String[] args) throws IOException {
		//封装数据源
		FileReader fr = new FileReader("StringDemo.java");
		//封装目的地
		FileWriter fw = new FileWriter("Copy.java");
		
		//读写数据
		//一次读写一个字符
//		int ch;
//		while((ch=fr.read())!=-1) {
//			fw.write(ch);
//		}
		
		//一次读写一个字符数组
		char[] chs = new char[1024];
		int len;
		while((len=fr.read(chs))!=-1) {
			fw.write(chs, 0, len);
		}
		
		//释放资源
		fw.close();
		fr.close();
	}
}

3.3 字符缓冲区流的概述和使用

3.3.1字符缓冲区流的概述
BufferedWriter
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
构造方法:
BufferedWriter(Writer out)
BufferedReader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
构造方法:
BufferedReader(Reader in)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值