黑马程序员_IO流(二)

----------- android培训java培训、java博客、java学习型技术博客、期待与您交流! --------------


本章主要的知识点总结:1、字节流的介绍及如何读取键盘录入

                                        2、转换流的运用,流操作的基本规律

                                        3、如何改变标准输入输出设备,使用异常的日志信息和查看系统信息

               

 

一、 字节流


      需求:想要操作图片数据,音乐数据,音频数据时,这时就要用到字节流。

InputStream抽象类

     此抽象类是表示字节输入流的所有类的超类。

方法:

      abstract int read()

从输入流中读取数据的下一个字节。

      int read(byte[] b)

从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

 InputStream ----> FileInputStream

        1、FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。

FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader

         2、构造方法:

FileInputStream(File file)

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

OutputStream抽象类

       此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。需要定义 OutputStream 子类的应用程序必须始终提供至少一种可写入一个输出字节的方法。

方法:

         void close()

关闭此输出流并释放与此流有关的所有系统资源。

           void flush()

刷新此输出流并强制写出所有缓冲的输出字节。

           void write(byte[] b)

将 b.length 个字节从指定的 byte 数组写入此输出流。

             void write(byte[] b, int off, int len)

将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

             abstract void write(int b)

将指定的字节写入此输出流.

OutputStream ----> FileOutputStream

1、文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。

    文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

           FileOutputStream 用于写入诸如图像数据之类的原始字节的流。

                要写入字符流,请考虑使用 FileWriter

2、构造方法:

                 FileOutputStream(File file)

创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

 

         读取键盘录入

     1、读取键盘录入:

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

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

     2、in

               public static final InputStream in

“标准”输入流。此流已打开并准备提供输入数据。

通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

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

 

 

二、读取转换流


       能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?

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

1.转换流

       Reader ---> InputStreamReader(java.io包)

  (1)InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。

      它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。

        要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:

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

(2)构造方法:

InputStreamReader(InputStream in)

创建一个使用默认字符集的 InputStreamReader。

(3)特有方法:

      void close()

关闭该流并释放与之关联的所有资源。

      String getEncoding()

返回此流使用的字符编码的名称。

     int read()

读取单个字符。

     int read(char[] cbuf, int offset, int length)

将字符读入数组中的某一部分。

     boolean ready()

判断此流是否已经准备好用于读取。


 2.BufferedReader中有readLine()方法,而且BufferedReader可作用于Reader及其子类。  InputStreamReader是Reader子类,故可以使用BufferedReader对其进行缓冲区技术高效操作.

 

3.代码示例:

//获取键盘录入对象。

InputStream in = System.in;

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

InputStreamReader isr = new InputStreamReader(in);

//为了提高效率,将字符串进行。使用BufferedReader.

BufferedReader bufr = new BufferedReader(isr);

String line = null;

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

{

if("over".equals(line))

break;

System.out.println(line.toUpperCase());

}

bufr.close();

 

三、写入转换流


1.写入转换流:

Writer ---> OutputStreamWriter(java.io包)

(1)public class OutputStreamWriterextends WriterOutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

       每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。

       注意,传递给 write() 方法的字符没有缓冲。

      为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。  例如:

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

(2)构造函数:

OutputStreamWriter(OutputStream out)

创建使用默认字符编码的 OutputStreamWriter。

(3)方法摘要

     void close()

关闭此流,但要先刷新它。

     void flush()

刷新该流的缓冲。

     String getEncoding()

返回此流使用的字符编码的名称。

    void write(char[] cbuf, int off, int len)

写入字符数组的某一部分。

     void write(int c)

写入单个字符。

     void write(String str, int off, int len)

写入字符串的某一部分。

   注意:

   BufferedWriter中有newLine()方法(用于写入行分隔符,即换行),而且       BufferedWriter可作用于Writer及其子类。

   OutputStreamReader是Writer子类,故可以使用BufferedWriter对其进行缓冲区技术高效操作.

 

四、流操作规律

{1)

源:键盘录入。

目地:控制台。

(2)需求:想把键盘录入的数据存储到一个文件中。

源:键盘。

目的:文件。

(3)需求:想要将一个文件的数据打印在控制台上。

源:文件。

目的:控制台。

1.流操作的基本规律:

最痛苦的就是流对象有很多。不知道该用哪一个。


通过两个明确来完成。

(1)明确源和目地。

源:输入流。InputStream Reader

目的:输出注。OutputStream Writer

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

是:字符流。

不是:字节流。

(3)当体系明确受制于人,再明确要使用哪个具体的对象。

通过设备来进行区分:

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

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

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

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

             是不是操作文本文件。

              是?这时就可以选择Reader

                这样体系就明确了。

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

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

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

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

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

BufferedReader bufr = new BufferedReader(fr);

(2)目的:OutputStream Writer

       是否是纯文本。

            是!Writer.

              设备:硬盘,一个文件。

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

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

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

BufferedWriter bufw = new BufferedWriter(fw);


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

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

那么分别分析

源:InputStream Reader

是不是纯文本?是!Reader

(1)设备:键盘,对应的对象是System.in.

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

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

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

用了Reader体系中转换流,InputStreamReader.

InputStreamReader isr = new InputStreamReader(System.in);

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

BufferedReader bufr = new BufferedReader(isr);

(2)目的:OutputStream Writer

是否是纯文本?是!Writer.

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

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

需要提高效率吗?需要。

BufferedWriter bufw = new BufferedWriter(fw);

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

(1)目的:OutputStream Writer

是否是纯文本?是!Writer.

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

但是FileWriter是使用的默认编码表-GBK。

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

所以要使用的对象是OutputStreamWriter.

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

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

需要高效吗?需要。

BufferedWriter bufw = new BufferedWriter(osw);

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

    注意:InputStreamReader ---> FileReader

(1)InputStreamReader的构造方法:

InputStreamReader(InputStream in, String charsetName)

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

(2)FileReader是封装了GBK编码表的字符流。是InputStreamReader的子类。

 

改变标准输入输出设备

1.System类(java.lang)的特有方法:

(1)setIn()

static void setIn(InputStream in)

重新分配“标准”输入流。

(2)setOut()

static void setOut(PrintStream out)

重新分配“标准”输出流。

2.OutputStream ---> FilterOutputStream ---> PrintStream

(1)PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

  它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,可调用其中一个 println 方法,或写入一个换行符或字节 ('\n')。

PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。

在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。

(2)构造方法:

PrintStream(String fileName)

创建具有指定文件名称且不带自动行刷新的新打印流。


      异常的日志信息


1.Throwable(java.util包)类的方法:

(1)void printStackTrace()

将此 throwable 及其追踪输出至标准错误流。

(2)void printStackTrace(PrintStream s)

将此 throwable 及其追踪输出到指定的输出流。

2.PrintStream类中的方法:

(1)void print(Object obj)

打印对象。

(2)void print(String s)

打印字符串

(3)void println(Object x)

打印 Object,然后终止该行。

(4)void println(String x)

打印 String,然后终止该行。

(5) void write(byte[] buf, int off, int len)

将 len 字节从指定的初始偏移量为 off 的 byte 数组写入此流。

 

   查看系统信息


1.System类(java.util)中的方法:

          static Properties getProperties()

       确定当前的系统属性。

2.Hashtable<Object,Object> ----> Properties类(java.util)

      (1)Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。

                属性列表中每个键及其对应值都是一个字符串。

       (2)特有方法:

            void list(PrintStream out)     将属性列表输出到指定的输出流。

3.代码:

Properties prop = System.getProperties();

//System.out.println(prop);

prop.list(new PrintStream("sysinfo.txt"));

 

  

 


 

 

 

 

                      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值