IO/字符流
前情提要:
需求:字节流读文本文件数据
一个汉字存储:
如果是GBK编码,占用2个字节如果是UTF-8编码,占用3个字节
/*
需求:字节流读文本文件数据
一个汉字存储:
如果是GBK编码,占用2个字节如果是UTF-8编码,占用3个字节
*/
public class FileInputstreamDemo {
public static void main(String[ ] args) throws IOException {
FileInputStream fis = new FileInputStream(name: "myCharStream\la.txt");
int by;
while ((by = fis.read()) != -1) {
system.out.print( (char) by);
}
fis.close();
}
}
一 为什么会出现字符流
由于字节流操作中文不是特别的方便,所以Java就提供字符流·
字符流=字节流+编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
二 编码表
1.基础知识:
(1)计算机中储存的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果
(2)按照某种规则,将字符存储到计算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。这里强调一下:按照A编码存储,必须按照A编码解析,这样才能显示正确的文本符号。否则就会导致乱码现象
(3)字符编码:就是一套自然语言的字符与二进制数之问的对应规则(A65)
2. 字符集:
(1)是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
(2)计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码.常见字符集有ASCII字符集、GBXXX字符集.Unicode字符集等
3.ASCII字符集:
(1)ASCII(American Standard Code for Information Interchange,美国信息交换标准代码):是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行健等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
(2)基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
4.GBXXX字符集:
(1)GB2312:简体中文码表。一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名等都编进去了,连在ASCIIl里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了
(2)GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等
(3)GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字。完全兼容GB2312标准。同时支持繁体汉字以及日韩汉字等
5.Unicode字符集:
(1)为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF32。最为常用的UTF-8编码
(2)UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编的码。它使用一至四个字节为每个字符编码
(3)编码规则:
128个US-ASCI字符,只需一个字节编码,拉丁文等字符,需要二个字节编码,大部分常用字(含中文),使用三个字节编码,其他极少使用的Unicode辅助字符,使用四字节编码
6.小结:采用何种规则编码,就要采用对应规则解码,否则就会出现乱码。
三. 字符串中的编码解码问题
编码:
byte] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码:
String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
String(byte ]l bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
上述都是采用的IDEA平台来编写代码。
publie elass StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
//定义一个字符串
String s =“中国”;
byte[ ] bys = s.getBytes(); //[-28,-72, -83,-27,-101, -67]bys m s.getBytes ("UTF-8" ); //[-28,-72, -83, -27,-101,-67]
byte[] bys = s.getBytes ( "GBK" ); / /[-42,-48,-71, -6]
System.out.print1n(Arrays.toString( bys ));
/ / String(byte[ ] bytes)小通过使用平台的默认字符集解码指定的字节数组来构造新的 stringString ss = new String ( bys);
/ /String(byte[ ] bytes, String charsetName)。通过指定的字符集解码指定的字节数组来构造新的 stringString ss = new String ( bys , "UTF-8");
String ss = new String(bys, charsetName: GB"");system.out.println(ss);
四. 字符流中的编码解码问题
字符流抽象基类
Reader:字符输入流的抽象类Writer:字符输出流的抽象类
字符流中和编码解码问题相关的两个类:
lnputStreamReader
OutputStreamWriter,
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"),"GBK");
osw.write("中国");
osw.close();
InputStreamReader isr=new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"),"GBK");
//一次读取一个字符数据
int ch;
while((ch=isr.read())!=-1){
System.out.println((char)ch;
}
isr.close();
五 字符流写数据的5种方式


osw.write(97);
osw.flush();
char[] chs={'a','b','c'};
osw.write(chs);
osw.write(0,chs.length);
osw.write(chs,1,2);
osw.write("abc");
osw.write("abcde",0,"abcde".length);
osw.write("abcde",1,3);
osw.close();
六 字符流读数据的两种方式

public class InputStreamReaderDemo i
public static void main(String[ j args) throws IOException {
//InputStreamReader (InputStream in)。创建一个使用默认字符集的InputStreamReader
InputStreamReader isr m naw InputStreamReader(naw FileInputStream、 name:"myCharStream\Losw.txt"));/ /int read ()。一次读一个字符数据
int ch;
while ((ch=isr.read( ) )!=-1) i[System.out.print( (char)ch);
//int read ( char[ ] cbuf),一次读一个字符数组数据char[]chs = new char[ 1024];
int ien;
while ((len = isr.read(chs) ) !=-1) i
system.out . print(new string(chs," offset: e,len));//释放资源
isr.close();
需求。
把模块目录下的ConversionStreamDemo.java复制到模块目录下的Copy.java思路。
1:根据数据源创建字符输人流对象2:根据自的地创建字符输出流对象3:读写数据,互制文件
4:释放资源
public class Copy JavaDemoe101{
publicstatic void main(string[ ] args) throws IOException {
/根据数据源创建字符输入流对象
InputStreamReader isr = new InputStreamReader(new FileInputStream( name: "myCharStream\\ConversionStreamDemo");
/根据目的地创建字符输出流对象
OutputStreamwriter o5w m new outputStreamNriter(new FileOutputStream( name: "myCharStream\\Copy.java"));
//读写数据,复制文件
//一次读写一个字符数据
int ch;
while((ch=isr.write())!=-1){
osw.write(ch);
}
//一次读写一个字符数组数据char[ ] chs = new char[ 1024];int ien;
while ( ( 1en=isr.read(chs) )l=-1) {
sw . write( chs , off:e, len) ;osw.close();
isr.close();//一次读写一个字符数组数据}
七 案例
案例:复制Java文件(改进版)
需求:把模块目录下的“ConversionStrearmDemo.java”复制到横块目录下的“Copy.java"
分析:
① 转换流的名字比较长,而我们常见的操作都是按照本地默认编的码实现的,所以,为了简化书写,转换流提供了对应的子类
②FileReader: 用于读取子付又件的便捷类
FileReader(String fileName)
③FileWriter:用于写入字符文件的便捷类
FileWriter(String fileName)
④数据源和目的地的分析
数据源:myCharStream\\ConversionStreamDemo.java ---读数据---Reader--- lnputStreamReader---FileReader 目的地: myCharStream\\ Copy.java ---写数据--- Writer --- OutputStreamWriter --- FileWriter
思路:①根据数据源创建字符输入流对象②根据目的地创建字符输出流对象③读写数据,复制文件
④释放资源
public class CopyJavaDemoe2 {
public static void main(String[ ] args) throws IOException[
//根据数据源创建字符输入流对象
FileReader fr= new FileReader( "myCharStream\\ConversionStreanDemo.java" );
//根据目的也创建字符输出流对象
FileWriter fw = new FileWriter( "myCharStream\lCopy.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,1en);
}
fw.close();
fr.close();
}
八 字符缓冲流
字符缓冲流:
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途
构造方法:
BufferedWriter(Writer out) ; BufferedReader(Reader in);
public class BufferedStreamDemoe1 {
publie static void main(String[ ] args) throws IOException {
//BufferedlWriter(Writer out)
//FiLelWriter fw = new FiLelWriter( "myCharStream\\bw.txt");
//BufferedWriter bw = new BufferedWriter(fw);
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\"bw.txt"));
bw. write("he1lo\r\n");
bw.write("wor1d\r\n");
bw.close();//一次读取一个字符数据
BufferedReader br=new BufferedReader(new FileReader("myCharStream\\bw.txt"));
int ch;
while((ch=br.read())!=-1){
System.out.println((char)ch);
//一次读取—个字符数组数据
char[ ]chs = new char[ 1024];
int len;
while ((len=br.read(chs))!=-1) {
system.out.print(new string(chs,0,len));
}}
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
