Java IO(一)

----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流!   ----------------------

JAVA IO(一)

 

Java中对数据的操作都是以"流"的方式来操作的,也就是我们常说的io流(InputStream OutputStream),流实际上是一个数据序列.

一、流的分类

    1.按流的方向分为2类:输入流、输出流;

    2.按流的数据单位不同分为2类:字节流、字符流

 

二、流的四大抽象基类

    1.字节流:InputStream、OutputStream

    2.字符流:Reader、Writer

    其他流都是都过继承这四大类而实现,很容易分辨,子类都是使用父类名做为后缀。字符流都是功能为开头,以Reader、Writer做为结尾,如FileInputStreamReader、FileOutputStreamWriter;子节流相同,不过是以InputStream、OutputStream结尾,还是以为File功能的举例,那就是FileInputStream、FileOutputStream;

    下图表示字节流部分的输入与输出的对应关系:

 

 

     黑马程序员--Java <wbr>IO(一)

 

三、流的基本方法

    1.InputStream

    int read()throws IOException

读取一个字节以整数形式返回,如果返回-1,已到输入流的末尾

    void close()throws IOException
关闭流释放内存资源

    2.OutputStream

     int write() throws IOExcepiton

向输出流写入一个字节数据

     void flush()throws IOException

将输出流中缓冲的数据全部写出

这是输出流特有的方法,因为输出时数据是先写入硬盘,然后再到设备的。

     void close() throws IOException

 关闭流释放内存资源   

    2.OutputStream

    void write(int c)throws IOException

向输出流写入一个字符数据

    void write(String str)throws IOException

将一个字符串中的字符写入到输出流

    void write (String str,int offset,int length)

将一个字符串从offset开始的length个字符写入到输出流

    void flush()throws IOException

将输出流中缓冲的数据全部写出到目的地

    Reader和Writer基本的放入与上面基本相同。

 

四、流的使用

字节流

FIleInputStream和FileOutputStream都属于节点流,他们的数据源都是硬盘上的一个具体文件。为打开一个文件以便输入,需要使用FileInputStream,同时使用String或File对象作为文件名使用。同样的输出到文件需要FileOutputStream。要注意的是,构造FIleInputStream,对应的文件必须是可读的,而构造FIleOutputStream时,若输出文件已存在,则必须是可覆盖的。写一个测试程序,使用这两个类,完成把复制文件的功能(把d:/java/Person.java复制到d:/Person.java)

 

public static void main(String[] args) {
   FileInputStream fis = null;//输入流
  FileOutputStream fos = null;//输出流
  String srcFileName = "d:/java/Person.java";
   try {
    //通过打开一个到实际文件的连接来创建一个 FileInputStream
    fis = new FileInputStream(srcFileName);
    // 创建一个向具有指定名称的文件中写入数据的输出文件流
   fos = new FileOutputStream("d:/Person.java");
    int i = 0;
    while (( i = fis.read()) != -1) {
     fos.write(i);
    }
   } catch (FileNotFoundException e) {   
    System.out.println("找不到文件" + srcFileName);
   } catch (IOException e) {   
    System.out.println("出现了错误");
   } finally {
    try {
     //一定要关闭,否则日积月累会造成内存泄露
    fis.close();//关闭输入流
    fos.close();//关闭输出流
   } catch (IOException e) {    
     e.printStackTrace();
    }
   }
  }

 

需要注意的是当我们使用完流时,一定要关闭,不然的话日积月累会造成内存泄露,这点对于我们自己的电脑无所谓,但是对于服务器端的应用程序来说就至关重要了,因为服务器是不经常重启的。关闭的代码最好写在finally里面,这样保证了无论如何这段代码都会被执行。

 

字符流   

字符流主要是用来处理字符的。Java采用16位的Unicode来表示字符。字符流类有两个基类Reader和Writer,继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符。继承自Writer的流都是用于输出单位为字符的数据。可以把上面那个复制文件的程序,改为使用FIleReader和FileWriter这两个字符流类来完成

//复制文件,使用字符流
 public static void main(String[] args) {
   FileReader fr = null;//输入流
  FileWriter fw = null;//输出流
  String srcFileName = "d:/java/Person.java";
   try {
    //通过打开一个到实际文件的连接来创建一个 FileReader 
    fr = new FileReader(srcFileName);
    // 创建一个向具有指定名称的文件中写入数据的输出字符流
   fw = new FileWriter("d:/Person.java");
    int i = 0;
    while (( i = fr.read()) != -1) {
     fw.write(i);
    }
   } catch (FileNotFoundException e) {   
    System.out.println("找不到文件" + srcFileName);
   } catch (IOException e) {   
    System.out.println("出现了错误");
   } finally {
    try {
     //一定要关闭,否则日积月累会造成内存泄露
    fr.close();//关闭输入流
    fw.close();//关闭输出流
   } catch (IOException e) {    
     e.printStackTrace();
    }
   }
  }


 这个程序和上面那个使用FIleInputStream和FileOutputStream进行文件复制,看似差不多,但是根本区别在于底层,第一个数据传输的单位是字节,第二个程序的传输单位是字符

缓冲流

缓冲流要套接在相应的节点流之上,对读写的数据提供了缓冲功能,可以减少对硬盘的读写次数,即保护了硬盘,也提高了读写的效率,同时增加了一些新的方法。Java为InputStream、OutputStream、Reader、Writer都提供了相应的缓冲流。就以BufferedInputStream和BufferedOutputStream这两个类为例来说明缓冲流,把复制文件的例子进行改写,把字节流套接在缓冲流之上

//复制文件,使用缓冲流
 public static void main(String[] args) { 
   FileInputStream fis = null;//输入流
  FileOutputStream fos = null;//输出流
  BufferedInputStream bis = null;//带缓冲的输入流
  BufferedOutputStream bos = null;//带缓冲的输出流
  String targetFileName = "d:/java/Person.java";
   try {
    //通过打开一个到实际文件的连接来创建一个 FileInputStream
    fis = new FileInputStream(targetFileName);
    //使用装饰模式,把字节流fis套接在缓冲流之上,为其提供缓冲
   bis = new BufferedInputStream(fis);
    // 创建一个向具有指定名称的文件中写入数据的输出文件流
   fos = new FileOutputStream("d:/Person.java");
    //使用装饰模式,把字节流fos套接在缓冲流之上,为其提供缓冲
   bos = new BufferedOutputStream(fos);
    int i = 0;
    while (( i = bis.read()) != -1) {
     bos.write(i);
    }
   } catch (FileNotFoundException e) {   
    System.out.println("找不到文件" + targetFileName);
   } catch (IOException e) {   
    System.out.println("出现了错误");
   } finally {
    try {
     //把缓冲流关闭,套接在缓冲流之上的字节流也随着被关闭
    bis.close();
     bos.close();
    } catch (IOException e) {    
     e.printStackTrace();
    }
   }
  }

 

五、文件处理

    文件操作时字符流最常见的形式;

     1.创建一个流对象时,该对象一被出示化就必须要明确被操作的文件。

     2.而且该问价你会被创建指定目录下。如果该目录有同名文件,会覆盖.

     如下示例:

             FileWriter fw=new FileWriter("D:\\soft\\33.txt");

     如果续写,调用 FileWriter(InputStream is,boolean bo)即可,通过设定true属性,能够使流成为一个"append"状态,在程序中重新加载时,它就不再是覆盖原文件了,而是紧跟着原来内容结果,加上新的数据。

     3.输出流需调用flush才能将写入数据全部迅速写入文件中。

     4.文件处理都需要捕获IOException,同时我们必须要将流关闭,因此,可以采用如下模板的异常处理:

    

try

      {

            fw =new FileWriter("k:\\demo.txt");

            fw.write("bbdfdf");

       }

       catch (IOException e)

        {

                  e.printStackTrace();

         }

         finally            //在finally中关闭流,保证资源的释放

         {

               try

               {

                      if(fw!=null)    //判断资源不为空,再进行关闭,保证了程序的健壮性

                            fw.close();

               }

               catch(IOException e)

               {

                       e.printStackTrace();

               }

          }

}


 

六、几点注意

1、不管是输入还是输出流,使用完毕后要close(),如果是带有缓冲区的输出流,应在关闭前调用flush()。
 
2、应该尽可能使用缓冲区,来减少IO次数,以提高性能。
 
3、能用字符流处理的不用字节流。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流!   ----------------------  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值