黑马程序员——Java基础IO(一)——IO流概述、字符流、字节流、流操作规律

来源:互联网 发布:深圳税友软件 编辑:程序博客网 时间:2024/06/05 06:38

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

黑马程序员——Java基础IO(一)——IO流概述、字符流、字节流、流操作规律

第一讲 IO概述

一、IO(Input Output)流

        1.IO流用来处理设备之间的数据传输

        2.Java对数据的操作是通过流的方式

        3.Java用于操作流的对象都在IO包中

        4.流按操作数据分为两种:字节流与字符流 

        5.流按流向分为:输入流,输出流。

二、IO流常用基类

        1.字节流的抽象基类:

                InputStream ,OutputStream。

        2.字符流的抽象基类:

                Reader ,Writer。

        注:由这四个类派生出来的子类名称都是 以其父类名作为子类名的后缀。

        如:InputStream的子类FileInputStream。

        如:Reader的子类FileReader。

三、IO流的继承体系

 

第二讲字符流

一、字符流读取文件

        1、建立一个流对象,将已存在的一个文件加载进流。如果文件不存在,或者它是一个目录,而不是一个常规文件,或者无法打开进行读取。会抛出FileNotFound异常。

FileReader fr = new FileReader(f);

        2.读取数据。

                1)读取单个字符。

                        int ch=0;

                        ch=fr.read();

                read()方法返回的是作为整数读取的字符,每调用一次read()方法就读取一个字符,如果达到流的末尾就返回-1。

                2)将字符读入数组。

                        创建一个临时存放数据的数组。

                                char[] buf = new char[1024];

                                int num=0;

                        调用流对象的读取方法将流中的数据读入到数组中

                                num=fr.read(buf);

                        此read方法返回实际读入到字符数组的字符个数,如果达到流的末尾就返回-1。

                        构建字符串,就可以打印出数据了。

                                System.out.println(new String(buf,0,num));

        3.加入缓冲技术,提高读取效率。

                BufferedReader bufr=new BufferedReader(fr);

                String line=null;

                while((line=bufr.readLine())!=null)

                {

                        System.out.println(line);

                }

                readLine()是缓冲流对象bufr的特有方法,返回读取的一行字符(不包括换行符),如果达到流的末尾就返回null。

                关闭缓冲,其实关闭缓冲区,就是关闭缓冲区中的流对象。就可以不用写fr.close();

                bufr.close();

        3.关闭资源。

                fr.close();

         注意:

        1.read方法配合while循环可以读取完文件所有的数据。

        2.readLine方法原理:无论是读一行。或者读取多个字符。其实最终都是在在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。相对于read()方法,   降低了一个一个字符的读取时出错的概率。

        3.无论是read()、read(buf)、readLine()如果发生 I/O 错误,抛出IOException,关闭缓冲流对象bufr.close() bufw.close() 发生错误会抛出IOException。所以要对发生错误就会抛出异常的代码进行try{}catch{}处理。

二、字符流——写入数据至文件

        1.创建流对象,建立数据存放文件

                FileWriter fw = new FileWriter("Test.txt");

                如果存储位置有Test.txt文件,则创建一个空文本的Test.txt覆盖原文件。

                如果不想覆盖原文件,想进行续写则加上true属性。

                FileWriter fw=new FileWriter("Test.txt",true);

        2.写入数据。

                方式一:调用流对象的写入方法,将数据写入流

                        fw.write("text");

                方式二:加入缓冲区,提高写入效率。

                        将需要被提高效率的流对象作为参数传递给缓冲区的构造函数

                                BufferedWriter bufw=new BufferedWriter(fw);

                                bufw.write("我是数据");

                        根据需求是否写入跨平台的换行符

                                bufw.newLine();

                        只要用到缓冲区,就要记得刷新。(关闭流同样会刷新,但为了排除意外事故,保证数据存在,建议写入一次就刷新一次)

                                bufw.flush();

                        其实关闭缓冲区,就是在关闭缓冲区中的流对象。就可以不用写fw.close();

                                bufw.close();

        3.关闭流资源,并将流中的数据清空到文件中。就是先flush再关闭资源,不然文件里面没有数据

                fw.close();

        注意:定义文件路径时,可以用“/”或者“\\”。反之视为相对路径(如“Test.txt”)。

三、字符流的缓冲区

        1.缓冲区的出现提高了对数据的读写效率。需要先将需要缓冲的流对象初始化到构造函数中。

        2.对应类:

                BufferedWriter

                BufferedReader

        3.缓冲区要结合流才可以使用。

        4.在流的基础上对流的功能进行了增强

        5、BufferedWriter、BufferedReader内部封装了一个字符数组,默认大小8kb。

示例一:拷贝文本文件

import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class TextFileCopy {public static void main(String[] args) throws IOException{//1.一个一个字符的拷贝textcopy_1();//2.每次拷贝指定大小的字符数组textcopy_2();}public static void textcopy_1() throws IOException{//1.创建读取文件流对象,关联文件。FileWriter fw=new FileWriter("c:/zzz.java");//2.建立文件写入流对象,关联文件。FileReader fr=new FileReader("C:\\copy_1.java");//3.读取文件数据。int ch=0;while((ch=fr.read())!=-1){fw.write(ch);}//4.关闭资源。close方法会先flush在释放Windows资源。fw.close();fr.close();}public static void textcopy_2() {//1.建立文件读取、写入流对象的引用。FileWriter fw=null;FileReader fr=null;//处理将会抛出异常的代码。try {//2.文件实例化fw=new FileWriter("c:/zzz.java");fr=new FileReader("C:\\copy_2.java");//3.读取文件数据,写入到目的地。char[] buf=new char[1024];int len=0;while((len=fr.read(buf))!=-1){fw.write(buf,0,len);}} catch (IOException e) {throw new RuntimeException("读写失败");}finally{//4.关闭资源。if(fr!=null){try {fr.close();} catch (IOException e) {throw new RuntimeException("读取文件流关闭失败");}}if(fw!=null){try {fw.close();} catch (IOException e) {throw new RuntimeException("写入文件流关闭失败");}}}}}
示例二:带缓冲区复制文本文件

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class Day19_03缓冲区复制文件 {public static void main(String[] args) {//1.建立文件读取、写入流对象的引用,避免变量不能跨代码块使用。BufferedWriter bufw=null;BufferedReader bufr=null;try {//2.实例化流对象,关联文件。bufr= new BufferedReader(new FileReader("C:\\java.txt"));bufw= new BufferedWriter(new FileWriter("C:\\javacopy.txt"));//3.读取文本数据。一次读取一行数据。//readLine方法的原理:无论是读一行,获取读取多个字符。其实最终都是在硬盘上一个一个读取。//所以最终使用的还是read方法一次读一个的方法。String line=null;while((line=bufr.readLine())!=null){bufw.write(line);bufw.newLine();//写入换行符(跨平台)bufw.flush();//将缓冲区的数据刷新至输出流对象中,将数据写入到文件}} catch (IOException e) {throw new RuntimeException("读写失败");}finally{//4.关闭资源。try {if(bufr!=null){bufr.close();}} catch (IOException e) {throw new RuntimeException("读取关闭失败");}try {if(bufw!=null){bufw.close();}} catch (IOException e) {throw new RuntimeException("写入关闭失败");}}}}

第三讲 装饰设计模式

一、定义:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。

二、特点

        1、装饰类通常会通过构造方法接收被装饰的对象。

        2、并基于被装饰类的对象的功能,提供更强的功能。

三、装饰和继承的区别:

        1、装饰模式比继承要灵活。避免了继承体系的臃肿,且降低了类与类之间的关系。

        2、装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰类都必须所属同一个接口或者父类。

        3、从继承结构转为组合结构。

注:1、在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。

        2、BufferedWriter、BufferedReader也是装饰类。

示例三:MyBufferedReader的例子就是最好的装饰设计模式的例子。

import java.io.FileReader;import java.io.IOException;import java.io.Reader;class MyBufferedReader extends Reader//Reader里面有抽象方法必须覆盖{//1.将FileReader对象传入,基于已有的功能,并提供加强功能。private FileReader r;MyBufferedReader(FileReader r){this.r=r;}//2.一次读一行数据。public String myReadLine() throws IOException{//定义一个临时容器。原BufferReader封装的是字符数组。//3.为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。StringBuilder sb = new StringBuilder();int num=0;while((num=r.read())!=-1){//识别换行符。Windows换行 \r\nif (num=='\r') {continue;} else if(num=='\n'){return sb.toString();}elsesb.append((char)num);}if(sb.length() != 0)return sb.toString();return null;}public void myClose() throws IOException{r.close();}//4.覆盖Reader类中的抽象方法。public void close() throws IOException{r.close();}public  int read(char[] cbuf, int off, int len)  throws IOException{return r.read(cbuf,  off,  len);}}public class Day19_05MybufferedReader {public static void main(String[] args)  throws IOException{//1.建立读取流对象,关联文件。FileReader fr=new FileReader("buf.txt");//2.加入自定义的缓冲包装读取流对象。MyBufferedReader myBuf=new MyBufferedReader(fr);//3.读取数据并,打印在控制台上。String line=null;while((line=myBuf.myReadLine()) !=null){System.out.println(line);}//4.关闭资源。myBuf.myClose();}}

四、行号LineNumberReader

LineNumberReader:

        1、跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。
        2、默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,并且可以通过调用 setLineNumber(int) 更改行号。但要注意的是,setLineNumber(int) 不会实际更改流中的当前位置;它只更改将由 getLineNumber() 返回的值。 
        3、可认为行在遇到以下符号之一时结束:换行符('\n')、回车符('\r')、回车后紧跟换行符。
示例四:行号
import java.io.FileReader;import java.io.IOException;import java.io.LineNumberReader;public class Day19_09LineNumberReader {public static void main(String[] args) throws IOException{//1.建立读取文件流对象。FileReader fr=new FileReader("copy.txt");LineNumberReader lnr=new LineNumberReader(fr);String line=null;//lnr.setLineNumber(100);//起始值从100开始while((line=lnr.readLine())!= null){System.out.println(lnr.getLineNumber()+":"+line);}lnr.close();}}

第四讲 字节流

一、字节流与字符流的不同

        1.基本操作与字符流类相同,但它不仅可以操作字符文件,还可以操作其他媒体文件。

        2.由于媒体文件数据中都是以字节存储的,所以,字节流对象可直接对媒体文件的数据写入到文件中,而可以不用再进行刷流flush动作。

二、字节流复制媒体文件步骤:

1、建立一个流对象,将已存在的一个文件加载进流。

        FileInputStream fis = new FileInputStream("山水间.mp3");

2、建立流对象,关联数据存放文件。

        FileOutputStream fos = new FileOutputStream("c:\\山水间copy.mp3");

加上true属性续写文件。

        FileOutputStream fos = new FileOutputStream("c:\\山水间copy.mp3",true);

注意:1、2步会抛出异常:

        FileNotFound - 如果文件不存在,或者它是一个目录,而不是一个常规文件,或者无法打开进行读取。

        SecurityException - 如果存在安全管理器,且其 checkRead 方法拒绝对文件进行读取访问。

3、读取数据、写入数据。

        1)方式一:读、写单个字节

                读取: int num = fis.read();

                写入: fos.write(num);

        2)方式二:读取、写入规定大小的字节数组

                读取: byte[] buf=new byte[1024];

                int len=0;

                len=fis.read(buf);//返回的是实际读取的字节数量

                写入:fos.write(buf,0,len);

        3)方式三:读取、写入文件大小的字节数组。

                byte[] buf=new byte[fis.available()];//定义一个刚刚好的缓冲区,不用在循环了

                读取: fis.read(buf);

                写入: fos.write(buf);

注意:可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。

        4)方式四:加入缓冲区提高读取数据的效率。

                缓冲读取流:BufferedInputStream bufis=new BufferedInputStream(fis);

                缓冲输出流:BufferedOutputStream bufos=new BufferedOutputStream(fos);

                        byte[] buf=new byte[1024];

                        int len=0;

                        len=bufis.read(buf);

                        fos.write(buf,0,len);

                        bufis.close();

                        bufos.close();

注意关闭了缓冲流对象,也就关闭了fis.close(); fos.close();

4、关闭资源

        fis.close();

        fos.close();

注意:字节流的Read()、write()方法

对于读取字节文件,当读取的字节是11111111是即-1,此时read方法会默认数据读取至流末,就结束了读取导致文件残缺,为了避免这种情况发生:

        1)read()方法返回的是4字节的int类型,API规定了这个方法会把读取的字节的高字节位置补零3个字节,因此如果读到数据,返回值必然在0到255之间,如果未读到返回-1;

        2)write(int)的参数是4个字节的int类型,实现类在写入时会强转为1个字节的byte类型,这个强转会发生去掉溢出的3个字节,比如write(256),实际写入的是0x00,也就等效于write(0);

示例五:复制图片

/*复制一个图片思路:1.用字节读取流对象和图片关联。2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。3.通过循环读写,图片读一段会查表,字符流别拷贝媒体文件。 * */import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class PicCopy{public static void main(String[] args) {//1.建立字节流对象引用。FileOutputStream fos=null;FileInputStream fis=null;//处理会抛异常的代码try {//2.流对象实例化。fos=new FileOutputStream("c:\\copy.png");fis=new FileInputStream("c:\\1.png");//3.读取字节数组数据byte [] buf=new byte[1024];int len=0;while((len=fis.read(buf))!=-1){//4.写入字节数组数据。fos.write(buf,0,len);}} catch (IOException e) {throw new RuntimeException("复制文件失败");}finally{//5.关闭资源。try {if(fis!=null)fis.close();} catch (IOException e1) {throw new RuntimeException("写入文件失败");}try {if(fos!=null)fos.close();} catch (IOException e2) {throw new RuntimeException("读取文件失败");}}}}



三、字节流缓冲区

1、基本操作与字符流类相同

但它不仅可以操作字符,还可以操作其他 媒体文件

示例六:字节流缓冲区复制mp3

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Mp3Copy {public static void main(String[] args) throws IOException {//计算复制文件的时间long start=System.currentTimeMillis();piccopy();long end=System.currentTimeMillis();System.out.println((end-start)+"毫秒");}public static void piccopy() throws IOException{//1.建立文件读取、写入流对象,关联文件。BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("D:\\时间煮雨.mp3"));BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("D:\\时间煮雨copy.mp3"));int by=0;byte [] buf=new byte[1024];//2.读取数据while((by=bufis.read(buf)) !=-1){//3.写入数据。bufos.write(buf,0,by);}//4.关闭资源。bufos.close();bufis.close();}}

示例七:自定义缓冲区复制MP3

import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;class MyBufferedInputStream{private InputStream in;private byte[] buf=new byte[1024];private int pos=0,count=0;MyBufferedInputStream(InputStream in){this.in=in;}public int myRead() throws IOException{//byte型&0xff向上转成int型if(count==0){count=in.read(buf);if(count<0)return -1;pos=0;byte b= buf[pos];count--;pos++;return b&0xff;}else if(count>0){byte b=buf[pos];count--;pos++;return b&255;}return -1;}public void myClose() throws IOException{in.close();}}public class MyBuffer {public static void main(String[] args) throws IOException{//计算复制时间。long start=System.currentTimeMillis();mp3_copy();long end=System.currentTimeMillis();System.out.println((end-start)+"毫秒");}public static void mp3_copy() throws IOException{//1.建立文件读取、写入流对象。MyBufferedInputStream bufis=new MyBufferedInputStream(new FileInputStream("D:\\小时代 - 时间煮雨.mp3"));BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("D:\\小时代 - 时间煮雨copy.mp3"));//2.读取数据int by=0;while((by=bufis.myRead()) !=-1)//read在提升{//3.写入数据。bufos.write(by);//write在强转 保证原数据不变 避免-1的发生。}//4.关闭资源。bufos.close();bufis.myClose();}}

四、补充:

一、核心功能实现类:所谓的核心功能实现类,也就是实现了最基础的写入功能——实现了原子操作write(int)和read()。ByteArrayOutputStream实现内存字节流的写入。

ByteArrayInputStream实现内存字节流的读取。

1、内存读写已经保证了多线程安全,但是文件读写没有保证;

2、内存读写不需要调用close方法;而文件读写使用文件系统,必须调用close方法释放文件资源;

3、字节流核心写入类都不带缓存功能,因此直接使用时无需调用flush方法;

4、FileOutputStream对象在创建时,就会执行一个native的open操作,如果是覆盖模式,此操作会立刻清除原文件内容,因此创建覆盖模式的FileOutputStream对象要非常谨慎,就算我们没做任何写入操作,文件内容也会被覆盖。

5、ByteArrayInputStream支持标记和重置功能,FileInputStream不支持;

6、ByteArrayInputStream的mark(int)方法中,参数无意义,随便传。

二、装饰功能——缓存读写BufferedOutputStream、BufferedInputStream:

FilterOutputStream在close方法中默认调用flush方法,这样在使用字节流写入的装饰子类时,无需在关闭前调用flush方法了。

五、注意事项:

1、缓存读写的装饰类都额外保证了读写操作的多线程安全性;

2、缓存读写的缓存大小默认都是8KB,可以通过构造方法指定,但读取操作的缓存是可变的,使用中大小可能发生变化;

3、缓存读取还附带实现了标记和重置功能,不同于ByteArrayInputStream的标记重置功能,BufferedInputStream读取提供的mark(int)的参数有意义,指定了标记在多少个字节内是起效的。

第五讲流操作规律

一、System类中的标准流

1、“标准”输入流

        static InputStream in 

2、“标准”输出流

        static PrintStream out

        PrintStream的父类是FilterOutputStream。

3、通过System类的setIn,setOut方法可以对默认设备进行改变

         将标准输入改成文件。

                System.setIn(newFileInputStream(“Demo.java”));

        将目的改成文件

                 System.setOut(newFileOutputStream(“info.txt”));

示例八:流改变标准输入输出设备

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintStream;public class TransStreamDemo{public static void main(String[] args) throws IOException{//System.setIn(new FileInputStream("Demo.java"));//1.将标准输出流目的地改为文件。System.setOut(new PrintStream("zzz.txt"));//2.建立带缓冲功能的键盘输入流、输出流、文件输出流对象。BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));BufferedWriter bufile=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("UTF.txt"),"UTF-8"));//3.读取键盘数据。String line=null;while((line=bufr.readLine())!=null){if("over".equals(line))break;//4.将数据写入到zzz.txtbufw.write(line.toUpperCase());//5.将数据按照UTF-8编码表,写入到UTF.txt中bufile.write(line);//刷流。bufile.newLine();bufile.flush();bufw.newLine();bufw.flush();}//6.关闭资源。bufr.close();bufw.close();}}

二、转换流InputStreamReader,OutputStreamWriter

 一、转换流的由来

         InputStreamReader 是字节流通向字符流的桥梁。

         OutputStreamWriter 是字符流通向字节流的桥梁。

方便了字符流与字节流之间的操作

二、转换流的应用

        字节流中的数据都是字符时,转成字符流操作更高效。

        例如:InputStreamReader将字节流通向字符流

                1)、获取键盘录入对象。

                        InputStream in = System.in;

                2)、将字节流对象转成字符流对象,使用转换流。

                        InputStreamReader isr = new InputStreamReader(in);

                3)、为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReade这样就可以调用readLine方法。

                        BufferedReader bufr = new BufferedReader(isr);

三、键盘录入最常见写法

        BufferedReader bufi = new BufferedReader(new InputStreamReader(System.in));

        打印到控制台的常见写法

        BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));

示例九:键盘录入数据将其小写字母变成大写字母打印到控制台上

/*读取键盘录入System.out:对应的是标准输出设备,控制台System.in:对应的是标准输入设备:键盘需求:通过键盘录入数据。当录入一行数据后,就将该行数据进行打印。如果录入的数据是over,那么就停止录入。通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。也就是readLine方法。能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?readLine方法时字符流BufferedReader类中的方法。而键盘录入的read方法是字节流InputStream的方法。那么能不能将字节流转成字符流在使用字符流缓冲区的readLine方法呢?*/import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;public class Day19_15IO读取键盘录入 {public static void main(String[] args) throws IOException{////1.获取键盘录入对象//InputStream in=System.in;////将字节流对象转成字符流对象,使用转换流。InputStreamReader//InputStreamReader isr=new InputStreamReader(in);////为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader//BufferedReader bufr=new BufferedReader(isr);//3句合并   键盘录入最常见写法。BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//OutputStream out=System.out;//OutputStreamWriter osw=new OutputStreamWriter(out);//BufferedWriter bufw=new BufferedWriter(osw);//建立控制台流对象。加入缓冲。BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));//2.每次读取一行字符串。String line=null;while((line=bufr.readLine())!=null){if("over".equals(line))break;//3.打印数据到控制台上bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();}//4.关闭资源。bufr.close();/*第二种方式StringBuilder sb=new StringBuilder();while(true){int ch=in.read();if(ch=='\r')continue;if(ch=='\n'){String s=sb.toString();if("over".equals(s))break;System.out.println(s.toUpperCase());sb.delete(0,sb.length());}elsesb.append((char)ch);}*/}}

三、流操作规律

流操作的基本规律,通过三个步骤来完成。

        1.明确源和目的。

                源:输入流。InputStream Reader

                目的:输出流。OutputStream Writer

        2.操作的数据是否是纯文本。

                是:字符流。

                不是:字节流。

        3.当体系明确后,在明确要使用哪个具体的对象。

                通过设备来进行区分:

                源设备:内存、硬盘、键盘

                目的设备:内存、硬盘、控制台。

示例分析:

        1.将一个文本文件中数据存储到另一个文件中。复制文件。

                1)源:因为是源,所以使用读取流。InputStream Reader

                        是不是操作文本文件。

                        是!这时就可以选择Reader

                        这样体系就明确了。

                2)接下来明确使用该体系中的哪个对象。

                        明确设备:硬盘。上一个文件。

                        Reader体系中可以操作文件的对象时FileReader

                                FileReader fr=new FileReader("a.txt");

                                BufferedReader bufr=new BufferedReader(fr);

                        是否需要提高效率:是!  加入Reader体系中的缓冲区BufferedReader

                        目的:OutputStream Writer

                        是否是纯文本。

                        是!Writer

                        设备:硬盘,一个文件

                        Writer体系中可以操作文件的对象FileWriter。

                        是否需要提高效率:是!  加入Writer体系中的缓冲区BufferedWriter

                                FileWriter fw=new FileWriter("a.txt");

                                BufferedWriter bufw=new BufferedWriter(fr);


        2.需求:将键盘录入的数据保存到一个文件中。

                1)这个需求中有源和目的存在。

                        那么分别分析

                        源:InputStream Reader

                        是不是纯文本?是!Reader

                2)设备:键盘。对应额是System.in.

                        不是选择Reader吗?System.in对应的不是字节流吗?

                        为了操作键盘的文本数据方便。转成字符流按照字符串操作时最方便的。

                        所以既然明确了Reader,那么就将System.in转换成Reader。

                        用了Reader体系中转换流,InputStreamReader

                                InputStreamReader isr=new InputStreamReader(System.in);

                        需要提高效率吗?需要!BufferedReader

                                BufferedReader bufr=new BufferedReader(isr);

                3)目的:OutputStream Writer

                        是否是纯文本? 是! Writer。

                        设备:硬盘。一个文件。 使用FileWriter。

                                FileWriter fw=new FileWriter("c.txt");

                        需要提高效率吗?需要。

                                BufferedWriter bufw=new BufferedWriter(fw);

        3、把录入的数据按照指定的编码表(utf-8),将数据存到文件中。

                1)目的:OutputStream Writer

                        是否是纯文本? 是! Writer。

                        设备:硬盘。一个文件。 使用FileWriter。

                2)但是FileWriter是使用默认编码表。GBK。

                        但是存储时,需要加入指定编码表。而指定的编码表只有转换流可以指定。

                        所以要使用的对象时OutputStreamWriter。

                        而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream

                                OutputStreamWriter osw= new OutputStreamWriter(new FileOutputStream("d.txt"), "UTF-8") 

                3)需要提高效率吗?需要。

                                BufferedWriter bufw=new BufferedWriter(osw);

                        所以记住。转换流什么使用。字符和字节之间的桥梁,通常涉及到字符编码转换时,需要用到转换流。

                        FileReader使用的默认编码GBK

                                OutputStreamWriter(OutputStream out, String charsetName) 

                                创建使用指定字符集的 OutputStreamWriter。

见示例八

第六讲系统信息与异常的日志信息

一、异常的日志信息

        当程序在执行过程中的时候,try代码块中的语句可能会抛出的异常,被catch语句捕捉到将抛出的错误信息以日志的形式存储起来,形成异常的日志信息。方便程序员分析错误。

示例十:异常的日志信息

import java.io.*;import java.text.*;import java.util.*;class  ExceptionInfo{public static void main(String[] args) {try{int[] arr =new int[2];System.out.println(arr[3]);}catch (Exception e){try{Date d=new Date();<span style="white-space:pre"></span>SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");String s=sdf.format(d);PrintStream ps=new PrintStream("info.log");System.setOut(ps);//修改输出流设备ps.println(s);//输出时间}catch (IOException ex){throw new RuntimeException("文件创建失败");}e.printStackTrace(System.out);//将异常信息数据写入到info.log}}}

二、系统信息

        1.获取系统信息:

                Properties getProperties()

        2.将信息输出到指定输出流中

                 void list(PrintStream out)

        3.将输出流中数据存入指定文件中

                new PrintStream("info.txt")

示例一十一:系统信息

import java.util.*;  import java.io.*;  class SystemInfo   {     public static void main(String[] args)      {          PrintStream ps = null;         try         {            //获取系统信息对象            Properties pop = System.getProperties();            //创建输出流对象,将输出流中数据存入指定文件中            ps = new PrintStream("info.txt");            //将属性列表输出到指定的输出流            pop.list(ps);         }         catch (Exception e)         {   throw new RuntimeException("获取系统信息失败。");         }      }  }

0 0
原创粉丝点击