javaee论坛

普通会员

225648

帖子

334

回复

348

积分

楼主
发表于 2019-11-18 08:54:02 | 查看: 1450 | 回复: 0

字符流(JavaIO的Reader和Writer)功能与InputStream和OutputStream非常类似,InputStream和OutputStream基于字节处理,而字符流(Reader和Writer)是基于字符处理。主要用于读写文本。

1.1Reader类的常用方法

Reader类是JavaIO中所有Reader的基类。子类包括FileReader,BufferedReader,InputStreamReader,StringReader和其他Reader。

read();读取字符输入流。读取字符输入流的下一个字符,返回一个字符,意味着这个返回值的范围在0到65535之间(当达到流末尾时,同样返回-1)。这并不意味着Reader只会从数据源中一次读取2个字节,Reader会根据文本的编码,一次读取一个或者多个字节。read(charcbuf[]);读取字符输入流。读取多个字符,存入字符数组cbuf,返回实际读入的字符数。read(charcbuf[],intoff,intlen);方法,读取字符输入流。每次读取len个字符,存入字符数组cbuf,从off下标开始存储。close();关闭当前流,释放与该流相关的资源,防止资源泄露。在带资源的try语句中将被自动调用。关闭流之后还试图读取字符,会出现IOException异常。1.2Reader类的子类:FileReader

​FileReader类从InputStreamReader类继承而来(间接继承了Reader)。该类按字符读取流中数据。

1.3FileReader构造方法和常用方法1.3.1构造方法

FileReader(Filefile);通过打开一个到实际文件的连接来创建一个FileReader,该文件通过文件系统中的File对象file指定。

FileReader(StringfileName);通过打开一个到实际文件的连接来创建一个FileReader,该文件通过文件系统中的路径名name指定。

(了解)FileReader(FileDescriptorfd);在给定从中读取数据的FileDescriptor的情况下创建一个新FileReader。

提示:FileDescriptor是“文件描述符”。

其中有三个属性:

in标准输入(键盘)的描述符(从键盘输入读取流)out标准输出(屏幕)的描述符(讲流输出到控制台上)err标准错误输出(屏幕)的描述符(将流以红色的字体输出到控制台上)

代码示例:

try{FileWriterfw=newFileWriter(FileDescriptor.out);fw.write("我是爱你的。");fw.flush();fw.close();}...

控制台输出:

1.3.2常用方法

test.txt文件内容(字符长度为17)

read();读取字符输入流。读取字符输入流的下一个字符,返回一个字符。

try{Filefile=newFile("test.txt");FileReaderfileReader=newFileReader(file);intread=fileReader.read();//默认第一次读取第一个字符System.out.println((char)read);}...

结果:

read(charcbuf[]);读取字符输入流。读取多个字符,存入字符数组cbuf,返回实际读入的字符数。

try{Filefile=newFile("test.txt");FileReaderfileReader=newFileReader(file);charc[]=newchar[20];intlen=fileReader.read(c);//System.out.println("读取的字符长度为:"+len);for(chard:c){System.out.print(d);}}...

结果:

read(charcbuf[],intoff,intlen);读取字符输入流。每次读取len个字符,存入字符数组cbuf,从off下标开始存储。

try{Filefile=newFile("test.txt");FileReaderfileReader=newFileReader(file);charc[]=newchar[20];intlen=fileReader.read(c,2,8);//读取8个字符存入c数组,从下标2开始存储System.out.println("读取的字符长度为:"+len);for(chard:c){System.out.print(d);}}

结果:

close();关闭当前流,释放与该流相关的资源,防止资源泄露。在带资源的try语句中将被自动调用。关闭流之后还试图读取字符,会出现IOException异常。

try{Filefile=newFile("test.txt");FileReaderfileReader=newFileReader(file);intread=fileReader.read();//System.out.println((char)read);fileReader.close();//通过close()来关闭流,以释放系统资源。}...//或者在这里关闭...finally{if(fileReader!=null)fileReader.close();}

注意:

通常不使用close会导致内存泄露,垃圾回收机制会回收,但是最好自己显式关闭OutputStream的作用是如FileOutStream,当不调用close的时候,不会将缓存刷入文件中。

所以:一般使用完IO流之后都要通过close()来关闭,以释放系统资源

2字符输出流2.1Writer类的常用方法write(Stringstr);将指定的字符串写入此输出流。write(char[]cbuf,intoff,intlen);将指定char数组中从偏移量off开始的len个字符写入此输出流。flush();用于清空缓存里的数据,并通知底层去进行实际的写操作。(强制把缓存区里面的数据写入到文件)close();关闭当前流,释放与该流相关的资源。2.2Writer类的子类:FileWriter

​FileWriter类从OutputStreamWriter类继承而来(间接继承Writer类)。该类按字符向流中写入数据。

2.3FileWriter构造方法和常用方法2.3.1构造方法FileWriter(Filefile);通过打开一个到实际文件的连接来创建一个FileWriter,该文件通过文件系统中的File对象file指定。FileWriter(Filefile,booleanappend);通过打开一个到实际文件的连接来创建一个FileWriter,该文件通过文件系统中的File对象file指定。如果第二个参数为true,则将字符写入文件末尾处,而不是写入文件开始处。FileWriter(StringfileName);通过打开一个到实际文件的连接来创建一个FileWriter,该文件通过文件系统中的路径名name指定。FileWriter(StringfileName,booleanappend);通过打开一个到实际文件的连接来创建一个FileWriter,该文件通过文件系统中的路径名name指定。如果第二个参数为true,则将字符写入文件末尾处,而不是写入文件开始处。FileWriter(FileDescriptorfd);在给定从中写入数据的FileDescriptor的情况下创建一个新FileReader。(可以向控制台输出文本流)。2.3.2常用方法

write(Stringstr);将指定的字符串写入此输出流。

try{Filefile=newFile("test.txt");WriterfileWriter=newFileWriter(file);fileWriter.write("十年之前,我不认识你。");fileWriter.flush();fileWriter.close();}...

结果:

write(intc);将指定的字符写入此输出流。

try{Filefile=newFile("test.txt");WriterfileWriter=newFileWriter(file);fileWriter.write('育');fileWriter.flush();fileWriter.close();}...

结果:

write(char[]cbuf);将cbuf字符数组写入此输出流。

try{Filefile=newFile("test.txt");WriterfileWriter=newFileWriter(file);char[]charArray="字符串转字符数组".toCharArray();fileWriter.write(charArray);fileWriter.flush();fileWriter.close();}

结果:

write(char[]cbuf,intoff,intlen);将cbuf字符数组,按偏移量off开始的len个字符写入此输出流。

try{Filefile=newFile("test.txt");WriterfileWriter=newFileWriter(file);char[]charArray="字符串转字符数组".toCharArray();fileWriter.write(charArray,1,5);//从偏移量1开始,写入5个字符。fileWriter.flush();fileWriter.close();}

结果:

write(Stringstr,intoff,intlen);

try{Filefile=newFile("test.txt");WriterfileWriter=newFileWriter(file);Stringstr="字符串也可以制定写的内容";fileWriter.write(str,3,5);fileWriter.flush();fileWriter.close();}

结果:

3字符缓存流(BufferedReader/BufferedWriter)

(BufferedReader/BufferedWriter)是带缓冲区的字符流,默认缓冲区大小是8Kb,能够减少访问磁盘的次数,提高文件读取性能;并且可以一次性读取一行字符。(类似管道套管道一样,不带缓冲的流只能一滴一滴流,套了管道后,可以让一滴一滴留到外面的管道后一次性流出。)

3.1字符缓存流构造方法3.1.1BufferedReaderBufferedReader(Readerin);创建一个默认缓冲区大小8Kb的字符缓冲输入流;BufferedReader(Readerin,intsz);创建一个字符缓冲输入流;并分配sz/byte大小的缓冲区。3.1.1BufferedWriterBufferedWriter(Writerout);创建一个默认缓冲区大小8Kb的字符缓冲输出流;BufferedWriter(Writerout,intsz);创建一个字符缓冲输出流;并分配sz/byte大小的缓冲区。3.2字符缓存流的常用方法:readLine(),newLine()

BufferedReader.readLine();在字符缓冲输入流读取字符的时候,可以一次性读取一行,并将游标指向下一行。

try{Filefile=newFile("test.txt");FileReaderfr=newFileReader(file);BufferedReaderbr=newBufferedReader(fr);Stringstr;while((str=br.readLine())!=null){System.out.println(str);}}

BufferedWriter.newLine();在字符串缓冲输出流写入字符的时候,默认是在一行写入,当需要换行的时候,调用newLine()实现文本换行。

try{Filefile=newFile("test.txt");FileWriterfw=newFileWriter(file);BufferedWriterbw=newBufferedWriter(fw);bw.write("写入一行的文本");bw.newLine();//换行bw.write("写入第二行的文本");bw.flush();//刷新缓冲区,强制写入文件中bw.close();}...4.字节流与字符流的区别

字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有哪些不同呢?

字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的

字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容

那开发中究竟用字节流好还是用字符流好呢?

在所有的硬盘上保存文件或进行传输的时候都是以字节的方法进行的,包括图片也是按字节完成,而字符是只有在内存中才会形成的,所以使用字节的操作是最多的。

如果要java程序实现一个拷贝功能,应该选用字节流进行操作(可能拷贝的是图片),并且采用边读边写的方式(节省内存)。

最好在流前面加上缓冲流,为了提高性能和读取速度

课后练习使用字符流读取一个字符文件,并把其中的所有小写字母变成大写字母,然后写入到另外一个文件中。publicstaticvoidsmallTOBig(FileaFile,FilebFile){if(aFile.exists()){try(FileReaderfReader=newFileReader(aFile);FileWriterfWriter=newFileWriter(bFile);){char[]cbuf=newchar[1024];intread=-1;while((read=fReader.read(cbuf))!=-1){Stringstring=newString(cbuf,0,read);StringupperCase=string.toUpperCase();fWriter.write(upperCase);}}catch(FileNotFoundExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}publicstaticvoidmain(String[]args){FileaFile=newFile("test.txt");FilebFile=newFile("a.txt");smallTOBig(aFile,bFile);}

(使用字符流实现)编写程序来实现如下功能

在D盘下创建一个目录Letter在控制台显示下列选项:1查看请假条2撰写请假条如果用户选择2,则提示用户撰写请假条,并把撰写的内容保存位文件,存入到Letter文件夹下。格式如下:请假人:王宝强请假日期:2016年8月15日请假原因:向法院起诉马蓉离婚…..先请假一天等等如果用户选择1,则在控制台输出请假条的内容。publicstaticvoidmain(String[]args){System.out.println("1查看请假条2撰写请假条");Scannersc=newScanner(System.in);intnextInt=sc.nextInt();switch(nextInt){case1:readMessage();break;case2:writeMessage();break;default:break;}}publicstaticvoidreadMessage(){try(FileReaderfrReader=newFileReader(newFile("Letter/b.txt"));){intread=-1;char[]cbuf=newchar[1024];while((read=frReader.read(cbuf))!=-1){Stringstring=newString(cbuf,0,read);System.out.println(string);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}privatestaticvoidwriteMessage(){Scannersc=newScanner(System.in);System.out.println("请假人:");Stringn1=sc.next();System.out.println("请假日期:");Stringn2=sc.next();System.out.println("请假原因:");Stringn3=sc.next();try(FileWriterfWriter=newFileWriter(newFile("Letter/b.txt"));){StringBufferstringBuffer=newStringBuffer();fWriter.write("请假人:"+stringBuffer.append(n1));fWriter.write("\r\n");fWriter.write("请假日期:"+stringBuffer.append(n2));fWriter.write("\r\n");fWriter.write("请假原因:"+stringBuffer.append(n3));fWriter.write("\r\n");}catch(IOExceptione){e.printStackTrace();}}

写一个程序,记录程序在运行时出现过的错误,保存成错误日志!。如:追加写入:true

在输入Int类型的时候输错,把这个记录写入到文件中。

在String类型转换int类型的时候如果出错,把错误的记录写入到文件中。

格式如下:

err:2017年3月30日15:26:33字符串转换Int失败不能把abc转成int类型。

err:2017年3月30日15:27:12Scanner输入类型错误,要求输入int,却输入了”xyz”。

提示:捕获程序有可能出现错误的地方,在catch语句中将错误的信息用自己的语言组织,写入到File中。

publicstaticvoidcollectErr(Filefile){Scannerscanner=newScanner(System.in);System.out.println("请输入你要输入的整数值");try{intnextInt=scanner.nextInt();}catch(Exceptione){try(FileWriterfWriter=newFileWriter(file,true);){SimpleDateFormatsimpleDateFormat=newSimpleDateFormat();Datedate=newDate();Stringformat=simpleDateFormat.format(date);fWriter.write(format+"符串转换Int失败不能把输入的转成int类型"+"\r\n");}catch(IOExceptione1){e1.printStackTrace();}System.out.println("找到一次错误");}}publicstaticvoidcollect2Err(Filefile){Scannerscanner=newScanner(System.in);try{System.out.println("请输入你要输入的字符型值");Stringnext=scanner.next();intparseInt=Integer.parseInt(next);}catch(NumberFormatExceptione){try(FileWriterfWriter=newFileWriter(file,true);){SimpleDateFormatsimpleDateFormat=newSimpleDateFormat();Datedate=newDate();Stringformat=simpleDateFormat.format(date);fWriter.write(format+"Scanner输入类型错误,要求输入int,却输入了xyz"+"\r\n");}catch(IOExceptione1){e1.printStackTrace();}System.out.println("又找到一次错误");}}publicstaticvoidmain(String[]args){Filefile=newFile("d.txt");collectErr(file);collect2Err(file);}

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017