java之IO字符流

1.转换流的引入

在项目中新建了一个a.txt的文件,内容是 hello中国。我现在用字节输入流来读取并输出到控制台。当然复制文件是没有问题的啦。编码是utf-8。

package cn;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileInputStreamDemo1 {
	public static void main(String[] args) throws IOException {
		//创建字节输入流对象
		InputStream is = new FileInputStream("a.txt");

		//读取数据
		int temp = 0;
		while((temp=is.read()) != -1){
			System.out.print((char)temp);
		}
		//释放资源
		is.close();
	}

}

hello

package cn;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileInputStreamDemo1 {
	public static void main(String[] args) throws IOException {
		//创建字节输入流对象
		InputStream is = new FileInputStream("a.txt");

		//读取数据
		byte[] b = new byte[1024];
		int len = 0;
		while((len=is.read(b)) != -1){
			System.out.println(new String(b,0,len));
		}
		//释放资源
		is.close();
	}

}

hello中国

到这里,各位看官,是否觉得,字节流处理中文也是可以的啦,但是如果第1023是个中文字符,那么就惨了吧,一个中文字符是2个字节的啦。那么截取的时候,可能只截取一半。

所以呢,由于字节流操作中文不是"特别"方便,所以,java就提供了转换流。

字符流=字节流+编码表。

2.编码表

编码表:由字符及其对应的数值组成的一张表。

计算机只能识别二进制数据,早期由来是电信号。

为了方便应用计算机,让它可以识别各个国家的文字。

就将各个国家的文字用数字来表示,并一一对应,形成一张表。

ASCII:美国标准信息交换码。用一个字节的7位可以表示。

ISO8859-1:拉丁码表,欧洲码表。用一个字节的8位表示。

GB2312:中国的中文编码表。

GBK:中国的中文编码表升级,融合了更多的中文文字符号。

GB18030:GBK的取代版本。

BIG-5码:通行于台湾、香港地区的一种繁体字编码方案,俗称"大五码"。

Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,java语言使用的就是unicode。

UTF-8:最多用三个字节来表示一个字符。

UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容:

它将Unicode编码为00000000-0000007F的字符,用单个字节来表示
它将Unicode编码为00000080-000007FF的字符用两个字节表示 
它将Unicode编码为00000800-0000FFFF的字符用3字节表示

3.编码和解码

首先,我来讲一个故事,情景设在抗战时期。那时候,我们的先辈,为了发送消息,都是通过某种手段,将明文转换为密文来发送。但是,各位看官,可能想明文是什么,密文又是什么鬼?比如:我们的先辈要发送“10月29号 凌晨2点 花果山水帘洞集合”,如果发报的人员,将这个字符串通过电报发送过去,那么就惨了,如果敌人一旦进行电报的拦截,那么我们的先辈就完蛋了,但是,我们的先辈们有这么傻吗?他们准备了一个小本子,里面记载了文字和数值对应的关系,比如我对应1,诸如此类,然后将上面的字符串,即“10月29号 凌晨2点 花果山水帘洞集合”,其实这就是明文了,通过那个小本子,当然专业的说话,这个小本本就是编码表,将“10月29号 凌晨2点 花果山水帘洞集合”转换为编码表对应的数值,然后通过电报发送过去,那么,接收方只要有和发送方一样的编码表就可以了。然后接收方在接收到电报的时候,需要通过编码表,将数值转换为字符串,即将密文转换为明文。那么,即使这中间,敌人截取了电报,也没卵用,因为他们没有编码表。

package com;

import java.util.Arrays;

/**
 * public byte[] getBytes(String charsetName):使用指定的字符串集合把字符串编码为字节数组
 * public String(byte[] bytes,String charsetName):通过指定的字符集解码字节数组
 * 
 * 编码:把看的懂的变成看不懂的 String-->byte[]
 * 解码:把看不懂的变成看的懂的byte[]-->String
 * 
 */
public class StringDemo {
	public static void main(String[] args) throws Exception {

		//编码  String-->byte[]

		String s = "你好";
		byte[] b = s.getBytes("utf-8");
		System.out.println("编码:"+Arrays.toString(b));//编码:[-28, -67, -96, -27, -91, -67]

		//解码 byte[]-->String

		String s1 = new String(b,"utf-8");
		System.out.println("解码:"+s1);//解码:你好
	}

}

编码:[-28, -67, -96, -27, -91, -67, -17, -68, -116, -28, -72, -106, -25, -107, -116]

解码:你好,世界

4.OutputStreamWriter:编码 是使用制定的字符集将字符编码为字节

package com;

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

/**
 * public OutputStreamWriter(OutputStream out) 根据默认编码把字节流转换为字符流
 * public OutputStreamWriter(OutputStream out,String charsetName) 根据指定编码将字节流转换为字符流
 *  
 * 字符流=字节流+编码表
 */
public class OutputStreamWriterDemo {
	public static void main(String[] args) throws IOException {
		//创建转换流对象
		Writer w = new OutputStreamWriter(new FileOutputStream("w.txt"),"utf-8");
		//输出
		w.write("你好,世界");
		//释放资源
		w.close();

	}

}

5.InputStreamReader:解码 是使用制定的字符集读取字节并解码为字符

package com;

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;

public class InputStreamReaderDemo {
	public static void main(String[] args) throws Exception{
		//创建转换流对象
		Reader r = new InputStreamReader(new FileInputStream("w.txt"), "utf-8");

		int temp = 0;
		while((temp = r.read()) != -1){
			System.out.print((char)temp);
		}

		//释放资源
		r.close();

	}
}

6.OutputStreamWriter的写数据方法

package cn;

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

/**
 * OutputStreamWriter的方法 
 * public void write(int c) 写入一个字符
 * public void write(char[] chuf) 写一个字符数组
 * public void write(char[] chuf,int off,int len) 写一个字符数组的一部分
 * public void write(String str) 写一个字符串
 * public void write(String str,int off,int len)写一个字符串的一部分
 */
public class OutputStreamWriterDemo {
	public static void main(String[] args) throws IOException {
		//创建转换流对象
		Writer w = new OutputStreamWriter(new FileOutputStream("wr.txt"));

		//public void write(int c) 写入一个字符
		w.write(‘a‘);
		w.write(97);

		//public void write(char[] chuf) 写一个字符数组
		char[] chs = new char[]{‘a‘,‘b‘,‘c‘,‘d‘,‘e‘};
		w.write(chs);

		//public void write(char[] chuf,int off,int len) 写一个字符数组的一部分
		w.write(chs, 0, 2);

		//public void write(String str) 写一个字符串

		w.write("我爱你");

		//public void write(String str,int off,int len)写一个字符串的一部分
		w.write("你爱我", 0, 1);

		/**
		 * 如果没有将转换流对象flush()或close()?
		 * 原因:字符=2字节
		 * 文件中数据存储的基本单位是字节。
		 */

		w.flush();
		//释放资源
		w.close();

	}

}

close()和flush()的区别?

close()的作用是关闭流对象,但是先刷新缓冲区。关闭之后,流对象不可以继续使用。

flush()的作用是刷新缓冲区,刷新之后,流对象可以继续使用。

7.InputStreamReader 读取数据

package cn;

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

/**
 * InputStreamReader 读取数据
 *  
 *  int read() 读取单个字符
 *  int read(char[] chs) 将字符读取入数组
 *  
 */
public class InputStreamReaderDemo {
	public static void main(String[] args) throws IOException {
		//创建转换流对象
		Reader r = new InputStreamReader(new FileInputStream("wr.txt"));

		//读取单个字符
		int ch = 0;
		while((ch = r.read()) != -1){
			System.out.print((char)ch);
		}

		//关闭流对象
		r.close();
	}
}
package cn;

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

/**
 * InputStreamReader 读取数据
 *  
 *  int read() 读取单个字符
 *  int read(char[] chs) 将字符读取入数组
 *  
 */
public class InputStreamReaderDemo {
	public static void main(String[] args) throws IOException {
		//创建转换流对象
		Reader r = new InputStreamReader(new FileInputStream("wr.txt"));

		//将字符读取入数组
		char[] chs = new char[1024];
		int len = 0;
		while((len = r.read(chs)) != -1){
			System.out.println(new String(chs,0,len));
		}

		//关闭流对象
		r.close();
	}
}

8.转换流复制文件

package cn;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

/**
 * 读取的是a.txt,要保证a.txt存在
 */
public class FileCopy {
	public static void main(String[] args) throws IOException {
		Reader r = new InputStreamReader(new FileInputStream("a.txt"));
		Writer w = new OutputStreamWriter(new FileOutputStream("b.txt"));

		//一次读取一个字符
		int ch = 0;
		while((ch = r.read()) != -1){
			w.write(ch);
		}

		r.close();
		w.close();

	}

}
package cn;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

/**
 * 读取的是a.txt,要保证a.txt存在
 */
public class FileCopy {
	public static void main(String[] args) throws IOException {
		Reader r = new InputStreamReader(new FileInputStream("a.txt"));
		Writer w = new OutputStreamWriter(new FileOutputStream("b.txt"));

		//读取到字符数组
		char[] chs = new  char[1024];
		int len = 0;
		while((len = r.read(chs)) != -1){
			w.write(chs,0,len);
		}

		r.close();
		w.close();

	}

}

9.FileWriter和FileReader

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

package cn;

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

/**
 * 数据源:a.txt 读取数据--字符转换流--InputStreamReader--FileReader
 * 
 * 目的地:b.txt 写入数据--字符转换流--OuputStreamWriter--FileWriter
 *
 */
public class FileCopy2 {
	public static void main(String[] args) throws IOException {
		Reader r = new FileReader("a.txt");
		Writer w = new FileWriter("b.txt");

		int ch = 0;
		while((ch = r.read()) != -1){
			w.write(ch);
		}

		r.close();
		w.close();
	}

}
package cn;

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

/**
 * 数据源:a.txt 读取数据--字符转换流--InputStreamReader--FileReader
 * 
 * 目的地:b.txt 写入数据--字符转换流--OuputStreamWriter--FileWriter
 *
 */
public class FileCopy2 {
	public static void main(String[] args) throws IOException {
		Reader r = new FileReader("a.txt");
		Writer w = new FileWriter("b.txt");

		char[] chs = new char[1024];
		int len = 0;
		while((len = r.read(chs)) != -1){
			w.write(chs, 0, len);
		}

		r.close();
		w.close();
	}

}
时间: 2024-11-05 02:48:21

java之IO字符流的相关文章

从零开始学Java之IO字符流懒人模式(自动生成属性类,方法类,界面类)

平时做一个项目都要建很多的属性类,方法类和View类,学了IO流之后想了一种办法,就是自己写一串代码,然后在文本文档里写class <类名>加上所有的属性,然后运行一下代码就自动生成了一个  <类名>.java   文件.用myeclipse打开就可以了.同样的道理,你写一个只有   class <类名> 的txt文本文档  点一下另一段代码就自动生成了一个方法类,里面带有增删改查四个简单方法的方法类,还有一个View类. 首先说一下,生成属性类的这段代码: packa

java 字节流和字符流转换类InputStreamReader,OutPutStreamReader

import java.io.*; public class BufferDemo { public static void main(String[] args) throws IOException { BufferedReader buf=null; buf=new BufferedReader(new InputStreamReader(System.in)); System.out.print("Please enter a number:"); String str=buf

java 字节流和字符流的区别 转载

转载自:http://blog.csdn.net/cynhafa/article/details/6882061 java 字节流和字符流的区别 字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,如图12-6所示. 下面以两个写文件的操作为主进行比较,但是在操作时字节流和字符流的操作完成之后都不关闭输出流.范例:使用字节流不关闭执行 Java

芯学苑:浅析Java字节流和字符流

1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可以从中读入一个字节序列的对象被称为输入流;能够向其写入一个字节序列的对象被称为输出流. 2. 字节流 Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据.Java中最基本的两个字节流类是InputStream和OutputStream,它们分别代表了组基本的输入字节流和输出字节流.Inpu

java学习之IO字符流

1 package com.io; 2 3 import java.io.*; 4 /** 5 * 文件字符流的读取 6 * @author ganhang 7 * 8 */ 9 public class FileReaderDemo { 10 public static void read(){ 11 File file =new File("1.txt"); 12 try { 13 FileReader fr=new FileReader(file); 14 StringBuffe

Java IO字符流与字节流

一.基本概念 流:从一端流向另一端,从源头到目的地. 始终与程序为中心,都是程序与文件|数组|网络连接|数据库进行操作. 二.IO流分类 1.流向: 输入流和输出流 2.数据: 字节流:二进制,可以处理文本文件,视频,音频等 . 字符流:文本文件,只能处理纯文本,全款为可见字符(.txt..html). 3.功能: 节点:包裹源头 处理:增强功能,提高性能. 三.字节流与字符流 1.字节流 输入流:InputStream int read(byte[] b) int read(byte[] b,

Java: IO 字符流

FileInputStream和FileOutputStream分别是InputStream和OutputStream的子类,都是字节流.下面例子中有三个方法可以读写字节流: 1.一个一个的 2.一组一组的,可以自定义字节数组的长度 3.使用available方法,可以返回目标文件的长度从而利用该特性建立一个刚刚好长度的字节数组.但该方法有使用风险,例如目标文件过大,一个电影或者一个大数据文件,则会导致超过虚拟机内存的大小,从而出现错误.所以使用该方法要评估风险,如果可以确定目标是小文件,则可以

重踏学习Java路上_Day21(字符流,io小结,案例)

1:字符流(掌握)    (1)字节流操作中文数据不是特别的方便,所以就出现了转换流.       转换流的作用就是把字节流转换字符流来使用.    (2)转换流其实是一个字符流        字符流 = 字节流 + 编码表    (3)编码表        A:就是由字符和对应的数值组成的一张表        B:常见的编码表            ASCII            ISO-8859-1            GB2312            GBK            G

java - io字符流

1.字符流是什么 字符流是可以直接读写字符的io流 字符流读取字符,就是要先读取到字节数据,然后转为字符,如果要写出字符,需要把字符转为字节再写出 2.FileReader FileReader类的read(),可以按照字符大小读数 读取的是单个字符,返回的是int 读取字符,如果已到达流的末尾,则返回-1 3.FileWrite 写出字符 拷贝: 什么时候使用字符流: 字符流也可以拷贝文本文件,但不推荐使用,因为读取时会把字节转为字符,写出时还要把字符转回字节 程序需要读取一段文本,或者需要写