java IO之字符流
1、字节流与字符流的区别
字节流处理单元为1个字节,操作字节和字节数组,而字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.
代码说明(以读取文件E:\tesst\test.txt 内容为例 test.txt)
字节流
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ReadTest {
//1、定义缓冲区大小可以是1024的整数倍
private static final int SIZE = 1024;
public static void main(String[] args) throws IOException {
//创建流
File file = new File("E:\\test\\test.txt");
FileInputStream fis = new FileInputStream(file);
byte []buf = new byte[SIZE];
int len = fis.read(buf);
String result = new String(buf, 0, len);// 将字节数组转成字符串,而且是按照默认的编码表(GBK)进行解码。
System.out.println(result);
//关闭资源
fis.close();
}
}
字节流String类的String(byte[] bytes, int offset, int length)构造方法是通过使用平台的默认字符集(即GBK码表)解码指定的byte子数组,构造一个新的String
字符流
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class ReadTest {
public static void main(String[] args) throws IOException{
// 1、创建字节流
File file = new File("E:\\test\\test.txt");
FileInputStream fis = new FileInputStream(file);
// 2、建立字节向字符转换流。
InputStreamReader isr = new InputStreamReader(fis);
int result = isr.read();
System.out.println((char)result);
int result2 = isr.read();
System.out.println((char)result2);
int result3 = isr.read();
System.out.println(result3);
//3、关闭资源
fis.close();
isr.close();
}
}
2、编码表
2.1编码表的由来
计算机只能识别二进制数据,早期由来是电信号来表示,为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表。
2.2常见的编码表
常见的编码表有:
- ASCII:美国标准信息交换码,用一个字节的7位可以表示。
- ISO8859-1:拉丁码表或欧洲码表,用一个字节的8位表示。
- GB2312:中国的中文编码表。
- GBK:中国的中文编码表升级,融合了更多的中文文字符号。
- Unicode:国际标准码,融合了多种文字,所有文字都用两个字节来表示,Java语言使用的就是Unicode。
- UTF-8:最多用三个字节来表示一个字符。
2.3编码与解码
所谓编码就是字符串变成字节数组(String→byte[]),代表方法为 str.getBytes(charsetName);而所谓解码就是字节数组变成字符串(byte[]→String),代表方法为 new String(byte[], charsetName);。关于编码与解码,有一个结论,即由UTF-8编码,自然要通过UTF-8来解码;同理,由GBK来编码,自然也要通过GBK来解码,否则会出现乱码。
3、字符流
3.1字符流类的层次结构
3.1.1输入流
3.1.2输出流
3.2常用的字符流
BufferedReader、BufferedWriter、PrintWrite
3.2.1转换流InputStreamReader\OutputStreamWriter
InputStreamReader 将字节流转换为字符流。是字节流通向字符流的桥梁。OutputStreamWriter 将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。
例 在文件中写入数据然后读出数据最后打印读出的数据
package com.xyq.read;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class StreamConverter {
public static void main(String[] args)throws IOException {
writeTest();
readTest();
}
public static void writeTest()throws IOException{
//1、创建流
File file = new File("tempFile\\test.txt");
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
//2、写出数据
osw.write("世界你好!");
//3、关闭资源
osw.close();
fos.close();
}
public static void readTest()throws IOException{
//1、创建流
File file = new File("tempFile\\test.txt");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
//2、读出入数据
char []cbuf = new char[1024];
int len = isr.read(cbuf);
String result = new String(cbuf, 0, len);
System.out.println(result);
//3、关闭资源
isr.close();
fis.close();
}
}
3.2.2转换流的子类,用于操作字符文件的便捷类FileReader\FileWriter
package com.xyq.read;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class SubTransStreamTest {
public static void main(String[] args)throws IOException {
writeTest();
readTest();
}
public static void writeTest() throws IOException{
//1、创建流
File file = new File("tempFile\\test.txt");
FileWriter fw = new FileWriter(file);
//2、写出数据
fw.write("世界你好!");
//3、关闭资源
fw.close();
}
public static void readTest()throws IOException{
//1、创建流
File file = new File("tempFile\\test.txt");
FileReader fr = new FileReader(file);
//2、读入数据
char []cbuf = new char[1024];
int len = fr.read(cbuf);
String result = new String(cbuf, 0, len);
System.out.println(result);
//3、关闭资源
fr.close();
}
}
3.2.3缓冲流BufferedReader\BufferedWriter
例 在硬盘上,创建一个文件并写入一些文字数据,然后读取文字数据,最后打印读取的文字数据
package com.xyq.read;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class CharBufferedStreamTest {
public static void main(String[] args)throws IOException {
writeTest();
readTest();
}
public static void writeTest()throws IOException{
//1、创建流
File file = new File("tempFile\\test.txt");
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
BufferedWriter bw = new BufferedWriter(osw);
//2、写出数据
for(int i=0; i<3; i++){
bw.write(i + "世界你好!");
bw.newLine();
bw.flush();
}
//3、关闭资源
bw.close();
osw.close();
fos.close();
}
public static void readTest()throws IOException{
//1、创建流
File file = new File("tempFile\\test.txt");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
BufferedReader br = new BufferedReader(isr);
//2、读入数据
String result = "";
while((result = br.readLine()) != null){
System.out.println(result);
}
//3、关闭资源
br.close();
isr.close();
fis.close();
}
}
3.2.4PrintWrite
向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。
与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。
此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用 checkError() 是否出现错误。
printWrint常用APIpackage com.xyq.read;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintStreamTest {
public static void main(String[] args) {
// printTest();
printAutoFlshTest();
printControllerTest();
}
/**
* 使用打印流写入到文件
*/
public static void printTest(){
File file = null;
PrintWriter out = null;
try {
//1、创建流
file = new File("tempFile\\test.txt");
//2、实例化printWriter打印对象,并开启自动刷新功能
out = new PrintWriter(file);
//3、写入数据
out.println("你好 世界 !");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.关闭资源
if(out != null){
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 使用自动刷新的打印流写入到文件
*/
public static void printAutoFlshTest(){
File file = null;
FileWriter fw = null;
PrintWriter out = null;
try {
//1、创建流
file = new File("tempFile\\test.txt");
fw = new FileWriter(file);
//2、实例化printWriter打印对象,并开启自动刷新功能
out = new PrintWriter(fw, true);
//3、写入数据
//将数据写入到文件
//因为开启了自动刷新功能,所以println相当于以下执行了以下方法
//printWriter.write(String string);写入字符
//printWriter.newLine(); 换行
//printWriter.flsh(); 冲刷数据
out.println("我开启了PrintWriter的自动缓冲刷新功能");
out.println("我将要被写入到文件中,等待被读取");
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.关闭资源
if(out != null){
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(fw != null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 读取文件内容,使用PrintWriter打印到控制台
*/
public static void printControllerTest(){
File file = null;
FileReader fr = null;
BufferedReader in = null;
PrintWriter out = null;
try {
//1、创建流
file = new File("tempFile\\test.txt");
fr = new FileReader(file);
in = new BufferedReader(fr);
//2、实例化printWriter打印对象,并开启自动刷新功能
out = new PrintWriter(System.out, true);
//3、输出数据
String result = "";
while((result = in.readLine()) != null){
//将数据输出到控制台
//因为开启了自动刷新功能,所以println相当于以下执行了以下方法
//printWriter.write(String string);写入字符
//printWriter.newLine(); 换行
//printWriter.flsh(); 冲刷数据
out.println(result);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.关闭资源
if(out != null){
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4、System类对IO的支持
package com.xyq.read;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class SystemIOTest {
public static void main(String[] args) {
BufferedReader bufr = null;
BufferedWriter bufw = null;
try {
//1、读取键盘录入
System.out.println("请输入你的想要输入的信息");
bufr = new BufferedReader(new InputStreamReader(System.in));
//2、创建输出流
bufw = new BufferedWriter(new OutputStreamWriter(System.out));
//3、输出读取到的信息
String result = "";
while((result = bufr.readLine()) != null){
if("over".equals(result)){
System.out.println("输入结束");
break;
}
bufw.write(result);//写出数据
bufw.newLine();//换行
bufw.flush();//冲刷
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、关闭资源
if(bufw != null){
try {
bufw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bufr != null){
try {
bufr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
上一篇: java的IO之字符流
下一篇: java中的IO流