黑马程序员——Java中IO流(字节流 字符流 其他流 )

来源:互联网 发布:日本女人化妆知乎 编辑:程序博客网 时间:2024/06/04 05:35

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

大多数的应用程序都需要实现与设备之间的数据传输,例如:键盘可以输入数据,显示器可以显示程序的运行结果等,此时,就需要用到java中的IO流操作来对数据进行处理

 

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

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

Java用于操作流的对象都在io包中

 

IO体系:

  流按操作数据

       |---字节流(InputStream   OutputStream

       |---字符流(Reader   Writer

  流按流向

       |---输入流

       |---输出流

字节流两个基类:InputStream   OutputStream

字符流两个基类:Reader   Writer

 

字符流:

字符流的特点:

既然IO流是用于操作数据的,那么数据的最常见体现形式是:文件

字符流常见的方法:

     close()方法:关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷到目的地中

      flush()方法:刷新流资源

close()flush()的区别在于:flush刷新后,流可以继续使用,close刷新后,会将流关闭

IO的异常处理方式:IO流在异常处理时,必须要使用finally,因为关闭流是必须要操作的

import java.io.*;

class  FileWriterDemo

{

         public static void main(String[] args)

         {

                   FileWriter fw=null;

                   try

                   {  

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

                     fw.write("7890123456");              

                   }

                   catch (IOException e)

                   {

                            System.out.println(e.toString());

                   }

                  finally

                   {

                            try

                            {

                                     if(fw!=null)

                                  {

                                    fw.close();

                                  }

                            }

                            catch (IOException e)

                       {

                                System.out.println(e.toString());

                       }                     

                   }                

         }

}

字符流的文本文件读取方式:

文本文件读取方式一:

read()方法:一次读一个字符,而且会自动往下读

文本文件读取方式二:

通过字符数组进行读取

拷贝文本文件图例:

字符流中加入缓冲区:

缓冲区的出现提高了对数据的读写效率

对应的类

BufferedReader

BufferedWriter

缓冲区要结合流才可以使用,只是在流的基础上对流的功能进行了增强

该缓冲区中提供了一个跨平台的换行符  newLine();

 

字符读取缓冲区中提供了一个一次读一行的方法,方便于对文本数据的获取。readLine

当返回null时,表示读到文件的末尾

字符流加入的例题:复制一个文本文件

import java.io.*;

class  BufferedDemo

{

         public static void main(String[] args) throws IOException

         {

                     BufferedWriter buffw=new BufferedWriter(new FileWriter("demo1_copy.java"));

                      BufferedReader buffr=new BufferedReader(new FileReader("demo1.java"));

                      String line=null;

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

                      {

                           buffw.write(line);

                                     buffw.newLine();

                                     buffw.flush();

                      }

                      buffr.close();

                      buffw.close();

         }

}

readLine()方法返回的时候只返回回车符之前的数据内容,并不返回回车符

 

字节流(InputStream  OutputStream) 

想要操作除了文本文件之外的东西,如:图片  MP3等就要用到字节流

InputStream的三种读取方式:

(1)      FileInputStream fis=new FileInputStream(“fos.txt”);

                 int ch=0;

                 while((ch=fis.read())!=-1)

                  {

                       System.out.println((char)ch)

                   }

                 fis.close();

(2)      FileInputStream fis=new FileInputStream(“fos.txt”);

                  byte[] buf=new byte[1024];

                  Int len=0;

                  while((len=fis.read(buf))!=-1)

                    {

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

                     }

                  fis.close();

 

(3)      FileInputStream fis=new FileInputStream(“fos.txt”);

                 byte[] buf=new byte[fis.available()];

                  fis.read(buf);

                 System.out.println(new String(buf));

                 fis.close();

字节流加入缓冲区:

   对应的类:

          BufferedOutputStream

          BufferedInputStream

 

读取键盘录入:

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

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

 

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

 

readLine方法是字符流BufferedReader类中的方法

而键盘录入的read方法是字节流InputStream的方法

那么能不能将字节流转成字符流在使用字符流缓冲区得readLine方法呢?

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

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

 

什么是字符流通向字节流?

就是我本身有一些我自己熟悉的文字,把它变成字节,Writer是写出去,把这些文件写出去,这些文字是以字节的形式存在的,而往里面录入的都是字符,通俗的一句话就是,往文件中录的的字符,而存在的是字节。

 

其实读取键盘录入的语句就是:

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

流操作的基本规律:

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

通过三个明确来完成:

1、明确源和目的

  源:输入流 InputStream Reader

目的:目的  OutputStream   Writer

2、操作的数据是否是纯文本

  是:字符流

  不是:字节流

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

  通过设备来进行区分

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

  目的设备:内存,硬盘(文件),控制台

练习:

将一个图片文件中数据存储到另一个文件中。复制文件,要按照以上格式完成三个明确

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

   是不是操作图片,是!这时就可以选择InputStream,这样体系就明确了

 

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

   明确设备:硬盘上的一个图片

    Reader体系中可以操作图片的对象是InputStream

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

InputStream is=new InputStream (“a.jpg”);

BufferedReader bufr=new BufferedReader(fr);

目的:OutputStream   Writer

    是否操作图片

    是!OutputStream  

    设备:硬盘上的一个图片

     Writer体系中可以操作图片的对象是OutputStream

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

OutputStream os=new OutputStream (“b.jpg”);

BufferedWriter bufw=new BufferedWriter(fw);

 

例题:将异常打印到文件上,并且显示异常的出现的时间

import java.io.*;

import java.util.*;

import java.text.*;

class ExceptionInfo

{

         public static void main(String[] args) throws IOException

         {

                   try

                   {

                            int[] arr=new int[2];

                            System.out.println(arr[3]);

                   }

                   catch (Exception e)

                   {

                            try

                            {

                                     Date d=new Date();

                                     SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 

                                     String s=sdf.format(d);

                                     PrintStream ps=new PrintStream("execption.log");

                                     ps.println(ps);

                                     System.setOut(ps);

                            }

                            catch (Exception ex)

                            {

                                     throw new RuntimeException("日志文件创建失败");

 

                            }

                            e.printStackTrace(System.out);

                   }

        

         }

}

其他流

打印流:(PrintStream  PrintWriter)

该流提供了打印方法,可以将各种数据累心过的数据都原样打印

 

字节打印流:

PrintStream

构造函数可以接收的参数类型

1.file对象    File

2.字符串路径    String

3.字节输出流   OutputStream

 

 

字符打印流

PrintWriter

1.file对象    File

2.字符串路径    String

3.字节输出流   OutputStream

4.字符输出流    Writer

import java.io.*;

class PrintDemo

{

                                             public static void main(String[] args) throws IOException

                                             {

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

 

                                               PrintStream ps=new PrintStream(new FileOutputStream("c:\\a.txt"));

 

                                               String line=null;

 

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

                                               {

                                                        if("over".equals(line))

                                                                 break;

                                                   ps.println(line.toUpperCase());

                                               }

 

                                                ps.close();

                                               buf.close();

                                             }

}

 

序列流(合并流):SequenceInputStream

管道流  PipedInputStreamPipedOutputStream

输入输出可以直接进行连接,通过结合线程使用

集合中涉及IO流是Properties

管道流是涉及到多线程的IO

RandomAccessFile:随机访问文件

特点:

该类不算是IO体系中的子类

而是直接继承自object

但是它是IO包中的成员,因为它具备读和写功能

内部封装了一个书u,而且通过指针对数组的元素进行操作

可以通过getFilePointer获取指针的位置

同时可以通过seek改变指针的位置

 

其实完成读写的原理就是内部封装了字节输入流和输出流

 

通过构造函数可以看出,该类只能操作文件

而且操作文件还有模式:只读r,读写rw

 

如果模式为只读r,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常

如果模式为读写rw,操作的文件不存在,会自动创建,如果存在不会覆盖

 

而且该对象的构造函数要操作的文件不存在,会自动创建,如果存在则不会覆盖

 

操作基本数据类型的流对象(DataStream):

DataInputStreamDataOutputStream

可以用于操作基本数据类型的数据的流对象

ByteArrayStream

用于操作字节数字的流对象

ByteArrayInputStream:在构造的时候需要接收数据源,而且数据源是一个字节数组

 

ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经能够内部封装了可变长度的字节数组 这就是数据目的地

 

因为这两个流对象都操作的数组,并没有使用系统资源

所以要,不用进行close关闭

 

在流操作规律讲解时:

 源设备

键盘  System.in  硬盘 FileStream   内存 ArrayStream

 目的设备

控制台 System.out 硬盘 FileStream   内存 ArrayStream

 

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

 

 

0 0
原创粉丝点击