黑马程序员 + 第19天 IO流

来源:互联网 发布:vb程序设计实践教程 编辑:程序博客网 时间:2024/05/02 05:01

------- android培训、java培训、期待与您交流! ----------


day19

1、字符写入流缓冲区BufferedWriter

缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要先有流对象BufferedWriter缓冲区中提供了一个跨平台的换行符newLine();

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

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

BufferedWriter bufw = new BufferedWriter(fw);

只要用到缓冲区,就要记得刷新flush();关闭缓冲区,就是在关闭缓冲区中的流对象close()

2字符读取流缓冲区:BufferedReader

该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。当返回null时,表示读到文件末尾。readLine方法返回的时候只返回回车符之前的数据内容并不返回回车符

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

BufferedReader bufr = new BufferedReader(fr);

3、通过缓冲区复制一个.java文件注意newLine()的运用):参见CopyTextByBuf.java

4、根据BufferedReader类中的特有方法readLine的原理,可以自定义一个类,其中包含一个功能和readLine一致的方法,来模拟BufferedReader。参见MyBufferedReaderDemo.java

5、装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,

基于被装饰对象已有的功能,提供更强的功能,那么自定义的该类称为装饰类

装饰类通常会通过构造方法接收被装饰的对象。  参见:PersonDemo.java

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

装饰类因为增强了已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。 参见:装饰和继承.java

6、LineNumberReader:跟踪行号的缓冲字符输入流,继承自BufferedReader。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号

参见LineNumberReaderDemo.java MyLineNumberReaderDemo.java

7、FileInputStream fis = new FileInputStream("fos.txt");

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

   byte[] buf = new byte[1024];  //最优选择

fos.write("abcde".getBytes()); //字符串转换为字节数组

8复制一个图片,思路: 参见:

1,用字节读取流对象和图片关联。

2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。

3,通过循环读写,完成数据的存储。

4,关闭资源。

建议不要用字符流去拷贝媒体文件,字节码会发生变化,只用来处理文字数据

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

9字节流的读一个字节的read方法为什么返回值类型不是byte,而是int

因为有可能会读到连续8个二进制1(对应的十进制是-1)的情况,那么就会存在数据还没有读完,就已经结束的情况。因为我们判断文件是否读取结束也是通过结尾标记-1来确定的。所以,为了避免这种情况将读到的字节byte进行int类型的提升并在保留原字节数据的情况前面了补了240,变成了int类型的数值。而在写入数据,即write时,则又进行了强转操作,只写入了int类型数据的最低8

参见MyBufferedInputStream.java

10读取键盘录入。 参见ReadIn.java

System.out:对应的是标准输出设备,控制台。

System.in:对应的标准输入设备:键盘。

InputStream in = System.in;  //同时利用StringBuilder来存储录入的数据

11、readLine方法是字符流BufferedReader类中的方法,而键盘录入的read方法是字节流InputStream的方法。那么能不能将字节流转成字符流再使用字符流缓冲区的readLine方法呢?InputStreamReader 是字节流通向字符流的桥梁

//获取键盘录入对象。

//InputStream in = System.in;

//使用转换流InputStreamReader将字节流对象转成字符流对象

//InputStreamReader isr = new InputStreamReader(in);

//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader

//BufferedReader bufr = new BufferedReader(isr);

//键盘的最常见写法,读取一行数据

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //readLine()

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

BufferReader提供了readLine方法,而BufferedWriter提供了newLine方法。

参见TransStreamDemo.java

12、流操作的基本规律:最痛苦的就是流对象有很多,不知道该用哪一个。

可以通过三个明确来完成。 参见TransStreamDemo2.java

1,明确源和目的

源:输入流。InputStream  Reader

目的:输出流。OutputStream  Writer

2,操作的数据是否是纯文本。 是:字符流。 不是:字节流。

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

通过设备来进行区分:

源设备:内存,硬盘。键盘

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

两张码表可以实现中文(GBKUTF-8),系统默认字符编码是GBK

InputStreamReader可以指定任意码表,而其子类FileReader指定码表为GBK

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

目的:OutputStream  Writer 是否是存文本?是!Writer

设备:硬盘。一个文件。使用 FileWriter(使用的默认编码表GBK

而题目要求在存储时,需要加入指定编码表utf-8,但指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。该转换流对象要接收一个可以操作的文件的字节输出流FileOutputStream

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

需要高效吗?需要。

BufferedWriter bufw = new BufferedWriter(osw);

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

14、改变标准输入输出

static void setIn(InputStream in):重新分配“标准”输入流。 

static void setOut(PrintStream out):重新分配“标准”输出流。

15、log4j:专门用于建立java异常信息的工具包。

Properties prop = System.getProperties();

//System.out.println(prop);

prop.list(new PrintStream("sysinfo.txt")); //系统信息输入到文件中

参见ExceptionInfo.java SystemInfo.java


原创粉丝点击