您的位置:首页 > 职场人生

黑马程序员_java基础学习IO流学习笔记

2015-08-21 00:28 633 查看


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

IO流  概述:

1、IO流:即InputOutput的缩写。

2、特点:

        1)IO流用来处理设备间的数据传输。

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

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

        4)流按操作数据分为两种:字节流和字符流。

        5)流按流向分为:输入流和输出流。

注意:流只能操作数据,而不能操作文件。

3、IO流的常用基类:

        1)字节流的抽象基流:InputStream和OutputStream

        2)字符流的抽象基流:Reader和Writer

注:此四个类派生出来的子类名称都是以父类名作为子类名的后缀,以前缀为其功能;如InputStream子类FileInputStream;Reader子类FileReader

 

 

IO的分类及应用

(1)IO流的四个基类

  A:字节流

   字节输入流

    InputStream

   字节输出流

    OutputStream

  B:字符流

   字符输入流

    Reader

   字符输出流

    Writer

  这四个都是抽象类。

  输入流:读取数据

  输出流:写入数据

(2)文件的写入数据

  对文本文件写入数据:

   Writer -- FileWriter

 

  FileWriter的构造方法:

   FileWriter(File file)

   FileWriter(String name)

   FileWriter(File file,boolean append)

   FileWriter(String name,boolean append)

示例:

import java.io.*; 

 

class FileWriterDemo  



    public static void main(String[] args)  

    { 

        writerDate("abcde");//写入数据  

        writerFrom("zheshi:\r\nshenma");//续写数据,并附换行操作  

    } 

 

    //在硬盘上创建一个文件并写入指定数据  

    public static void writerDate(String s) 

    { 

        FileWriter fw=null; 

        try 

        { 

            fw=new FileWriter("demo.txt");//创建文件  

            fw.write(s);//将数据写入流  

        } 

        catch (IOException e) 

        { 

            throw new RuntimeException("写入失败"); 

        } 

        finally 

        { 

            if(fw!=null) 

                try 

                { 

                    fw.close();//将写入流的数据刷到指定文件内,并关闭流资源  

                } 

                catch (IOException e) 

                { 

                } 

        } 

    } 

 

    //对已有文件的数据续写指定数据  

    public static void writerFrom(String s) 

    { 

        FileWriter fw=null; 

        try 

        { 

            fw=new FileWriter("demo.txt",true);//传递一个true参数,代表不覆盖已有的文件。  

            fw.write(s); 

        } 

        catch (IOException e) 

        { 

            throw new RuntimeException("写入失败"); 

        } 

        finally 

        { 

            try 

            { 

                if(fw!=null) 

                    fw.close(); 

            } 

            catch (IOException e) 

            { 

            } 

        } 

    } 



 

 

 

  字符输出流写入数据的基本步骤:

   A:创建字符输出流对象

   B:调用该对象的write方法

   C:释放资源

  代码体现:

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

   fw.write("hello,io,我来了");

   fw.flush();

   fw.close();

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

示例:

import java.io.*; 

class  FileReaderDemo 



    public static void main(String[] args)  

    { 

        //第一种读取方式  

        singleCharReader(); 

        //第二种读取方式  

        arrayCharReader(); 

    } 

 

    //第一种读取方式,单个字符读取  

    public static void singleCharReader() 

    { 

        FileReader fr=null; 

        try 

        { 

             

            fr=new FileReader("demo.txt");//读取文件位置和文件名  

            for (int ch=0;(ch=fr.read())!=-1 ; ) 

            { 

                System.out.print((char)ch); 

            } 

        } 

        catch (IOException e) 

        { 

            throw new RuntimeException("读取失败"); 

        } 

        finally 

        { 

            try 

            { 

                if(fr!=null) 

                    fr.close();//关闭读取流资源  

            } 

            catch (IOException e) 

            { 

            } 

        } 

    } 

 

    //第二种读取方式,通过字符数组进行读取  

    public static void arrayCharReader() 

    { 

        FileReader fr=null; 

        char[] arr=new cha
13641
r[1024];//定义一个字符数组,用于临时存储读取的字符  

        try 

        { 

            //读取一个.java文件,并打印在控制台上。  

            fr=new FileReader("FileReaderDemo.java"); 

            for (int len=0;(len=fr.read(arr))!=-1 ; ) 

            { 

                //显示字符数组的字符个数  

                System.out.print(new String(arr,0,len)); 

            } 

        } 

        catch (IOException e) 

        { 

            throw new RuntimeException("读取失败"); 

        } 

        finally 

        { 

            if(fr!=null) 

                try 

                { 

                    fr.close(); 

                } 

                catch (IOException e) 

                { 

                } 

        } 

    } 



 

 

 

      flush和close的区别:

    flush刷新缓冲区,close刷新缓冲区,并释放资源。

    flush刷新缓冲区后,流对象还可以继续使用,close释放资源后,

     流对象不能被使用。

   流操作一定要调用close方法的原因:

    创建字符输出流对象的时候:不仅仅是在堆内存创建了java对象,

    并且使用了系统资源创建了文件对象,当程序结束后,java的对象

    会自动变成垃圾,被回收。 而系统的资源就一直在被使用,所以,

    我们需要调用close方法,就是去通知系统,你创建文件时候使用的

    资源可以释放了。

  两个小知识点:

   如何追加数据,而不是覆盖数据:

    使用带两个参数的构造方法,第二个参数表示是否是追加数据,写为true即可。

   数据追加或者写入的时候,如何换行:

    换行在不同的操作系统中,对应的字符不一样:

    windows: \r\n

    linux: \n

    有些软件,对不同的换行都是识别的,比如:editplus

    但是,windows自带的记事本只能识别\r\n。

   

  加入异常处理:

    public class FileReaderTest4 {

    public static void main(String[] args) {

     FileWriter fw = null;

     try {

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

     fw.write("hello,我是荣斌");

     fw.flush();

     } catch (IOException e) {

      e.printStackTrace();

     } finally {

     if(fw!=null){

     try {

     fw.close();

     } catch (IOException e) {

     e.printStackTrace();

        }

       }

      }

     }

    }

(3)文件的读取数据

  对文本文件读取数据:

   Reader -- FileReader

 

  FileReader的构造方法:

   FileReader(File file)

   FileReader(String name)

  字符输入流读取数据的基本步骤:

   A:创建字符输入流对象

   B:调用该对象的read方法

   C:释放资源

  代码体现:

  

   一次读写一个字符代码如下:

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

  

   //一次读写一个字符

   int num = 0;

   while((num=fr.read())!=-1)

   {

    System.out.print((char)num);

   }

   fr.close();

   一次读写一个字符数组代码如下:

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

  

   //一次读写一个字符数组

   char[] chs = new char[1024]; //1024的整数倍

   int len = 0; //存储读取的实际长度

   while((len=fr.read(chs))!=-1)

   {

    System.out.print(new String(chs,0,len));

   }

   fr.close();

(4)文件的复制

  数据源:

   来源:a.txt

   FileReader -- 读取数据

  目的地:

   目的:b.txt

   FileWriter -- 写入数据

示例:

/*

需求:

将c盘一个文本文件复制到e盘、

复制的原理:

其实就是将c盘下的文件数据存储到e盘的一个文件中。

步骤:

1、在e盘创建一个文件。用于存储c盘文件中的数据。

2、定义读取流和c盘文件关联。

3、通过不断的读写完成数据存储。

4、关闭资源。

*/ 

import java.io.*; 

  

class ReaderWriterTest 



       publicstatic void main(String[] args)  

       { 

              //调用复制方法  

              //copy_1();  

              copy_2(); 

       } 

       //用第一种读取方式进行复制  

       publicstatic void copy_1() 

       { 

              FileWriterfw=null; 

              FileReaderfr=null; 

              try 

              { 

                     //关联读取和写入的文件  

                     fw=newFileWriter("E:\\HelloWorld.java"); 

                     fr=newFileReader("C:\\HelloWorld.java"); 

                     for(int ch=0;(ch=fr.read())!=-1 ; ) 

                     { 

                            fw.write(ch);//一个字符一个字符写入  

                     } 

              } 

              catch(IOException e) 

              { 

                     thrownew RuntimeException("读写失败"); 

              } 

              finally 

              { 

                     if(fr!=null) 

                            try 

                            { 

                                   fr.close();//对读取流和写入流分别关闭  

                            } 

                            catch(IOException e) 

                            { 

                            } 

                     if(fw!=null) 

                            try 

                            { 

                                   fw.close(); 

                            } 

                            catch(IOException e) 

                            { 

                            } 

              } 

       } 

  

       //第二种读取方式进行复制  

       publicstatic void copy_2() 

       { 

              FileWriterfw=null; 

              FileReaderfr=null; 

              try 

              { 

                     //关联读取和写入的文件  

                     fw=newFileWriter("E:\\HelloWorld.java"); 

                     fr=newFileReader("C:\\HelloWorld.java"); 

                     char[]arr=new char[1024]; 

                     for(int len=0;(len=fr.read(arr))!=-1 ; ) 

                     { 

                            fw.write(arr,0,len);//利用数组一次存入数组中的字符  

                     } 

              } 

              catch(IOException e) 

              { 

                     thrownew RuntimeException("读写失败"); 

              } 

              finally 

              { 

                            try 

                            { 

                                   if(fr!=null) 

                                          fr.close(); 

                            } 

                            catch(IOException e) 

                            { 

                            } 

                            finally 

                            { 

                                   if(fw!=null) 

                                          try 

                                          { 

                                                 fw.close(); 

                                          } 

                                          catch(IOException e) 

                                          { 

                                          } 

                            }      

              } 

       } 



 

 

  3:带缓冲的字符流对象

(1)字符流体系图

  Reader 的功能

   read()

   read(char[] chs)

   close()

  

   FileReader:没有特殊方法

   BufferReader:readLine()

  Writer  的功能

   write(int ch)

   write(String str)

   write(String str,int start,int end)

   write(char[] chs)

   write(char[] chs,int start,int end)

   flush()

   close()

  

   FileWriter:没有特殊方法

   BufferedWriter:newLine()

(2)字符缓冲输出流写入数据

  代码体现:

BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));

   bw.write("哈哈,该下课了");

   bw.newLine();

   bw.flush();

   bw.close();

(3)字符缓冲输入流读取数据

  代码体现:

  

   方式1:

BufferedReader br = new BufferedReader(new FileReader("bw.txt"));

    int num = 0;

    while((num=br.read())!=-1)

    {

     System.out.print((char)num);

    }

    br.close();

   方式2:

    BufferedReader br = new BufferedReader(new FileReader("bw.txt"));

    char[] chs = new char[1024];

    int len = 0;

    while((len=br.read(chs))!=-1)

    {

     System.out.print(new String(chs,0,len));

    }

    br.close();

   方式3:

    BufferedReader br = new BufferedReader(new FileReader("bw.txt"));

    String line = null;

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

    {

     System.out.println(line);

    }

    br.close();

 

(4)字符缓冲流复制文本文件

示例:

/*

需求:使用缓冲技术copy一个文本文件

*/ 

import java.io.*; 

 

class BufferedCopyDemo  



    public static void main(String[] args)  

    { 

         

        BufferedWriter bfw=null; 

        BufferedReader bfr=null; 

        try 

        { 

            //创建写缓冲对象  

            bfw=new BufferedWriter(new FileWriter("ReaderWriterTest_copy.txt")); 

            //创建读缓冲对象  

            bfr=new BufferedReader(new FileReader("ReaderWriterTest.java")); 

            //利用BufferedReader提供的readLine方法获取整行的有效字符。直到全部获取  

            for (String line=null; (line=bfr.readLine())!=null; ) 

            { 

                bfw.write(line);//写入指定文件中  

                bfw.newLine();//换行  

                bfw.flush();//将缓冲区数据刷到指定文件中  

            } 

             

        } 

        catch (IOException e) 

        { 

            throw new RuntimeException("文件copy失败"); 

        } 

        finally 

        { 

            if(bfw!=null) 

                try 

                { 

                    bfw.close();//关闭写入流  

                } 

                catch (IOException e) 

                { 

                    throw new RuntimeException("写入流关闭失败"); 

                } 

            if(bfr!=null) 

                try 

                { 

                    bfr.close();//关闭读取流  

                } 

                catch (IOException e) 

                { 

                    throw new RuntimeException("读取流关闭失败"); 

                } 

        } 

    } 



 

装饰设计模式

1、简述

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

2、特点

        装饰类通常都会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。

3、装饰和继承的区别:

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

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

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

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

示例:上面讲到的MyBufferedReader的例子就是最好的装饰设计模式的例子。

 

 
       
流操作规律IO 字节流

一、概述

1、字节流和字符流的基本操作是相同的,但字节流还可以操作其他媒体文件。

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

3、读写字节流:InputStream   输入流(读)

                             OutputStream  输出流(写)

4、为何不用进行刷流动作:

        因为字节流操作的是字节,即数据的最小单位,不需要像字符流一样要进行转换为字节。所以可直接将字节数据写入到指定文件中。

5、InputStream特有方法:

        int available();//返回文件中的字节个数

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

/*

练习:

复制一个图片

思路:

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

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

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

4、关闭资源。

*/

import java.io.*;

class  CopyPic

{
public static void main(String[] args) 
{
//常用方法复制
byteArrayCopy();
//利用输入流的available方法进行复制
availableCopy();
//利用available方法对复制文件大小有限制,慎用
}

//使用available方法进行复制
public static void availableCopy()
{
FileInputStream fis=null;
FileOutputStream fos=null;
try
{
//关联要复制的文件
fis=new FileInputStream("C:/Users/asus/Desktop/1.jpg");
//指定复制的路径
fos=new FileOutputStream("C:/Users/asus/Desktop/3.jpg");
//利用available方法指定数组长度
byte[] b=new byte[fis.available()];

fis.read(b);//复制关联文件数据

fos.write(b);//粘贴到指定路径

}
catch (IOException e)
{
throw new RuntimeException("图片复制失败");
}
finally
{
try
{
if(fis!=null)
fis.close();//关闭输入字节流
}
catch (IOException e)
{
throw new RuntimeException("读取字节流关闭失败");
}
try
{
if(fos!=null)
fos.close();//关闭输出字节流
}
catch (IOException e)
{
throw new RuntimeException("写入字节流关闭失败");
}
}
}
//使用读数组方式进行复制
public static void byteArrayCopy()
{
FileInputStream fis=null;
FileOutputStream fos=null;
try
{
//关联要复制的文件
fis=new FileInputStream("C:/Users/asus/Desktop/1.jpg");
//指定复制的路径
fos=new FileOutputStream("C:/Users/asus/Desktop/2.jpg");
//利用数组的读取方式
byte[] b=new byte[1024];
int len=0;
while ((len=fis.read(b))!=-1)//复制文件的全部数据
{
fos.write(b,0,len);//粘贴到指定路径
}
}
catch (IOException e)
{
throw new RuntimeException("图片复制失败");
}
finally
{
try
{
if(fis!=null)
fis.close();//关闭输入字节流
}
catch (IOException e)
{
throw new RuntimeException("读取字节流关闭失败");
}
try
{
if(fos!=null)
fos.close();//关闭输出字节流
}
catch (IOException e)
{
throw new RuntimeException("写入字节流关闭失败");
}
}
}

}

    

二、字节流缓冲区

        同样是提高了字节流的读写效率。

1、读写特点:

        read():会将字节byte型值提升为int型值

        write():会将int型强转为byte型,即保留二进制数的最后八位。

2、原理:将数据拷贝一部分,读取一部分,循环,直到数据全部读取完毕。

        1)先从数据中抓取固定数组长度的字节,存入定义的数组中,再通过然后再通过read()方法读取数组中的元素,存入缓冲区。

        2)循环这个动作,直到最后取出一组数据存入数组,可能数组并未填满,同样也取出包含的元素。

        3)每次取出的时候,都有一个指针在移动,取到数组结尾就自动回到数组头部,这样指针在自增。

        4)取出的时候,数组中的元素在减少,取出一个,就减少一个,直到减到0即元素取完。

        5)当文件中的全部数据都被读取出时,read()方法就返回-1。

3、自定义读取字节流缓冲区
示例:
/*

自定义字节流读取缓冲区

思路:

1、定义一个固定长度的数组

2、定义一个指针和计数器用于读取数组长度,和计数数组元素是否取完为0

3、每次将字节数据存入元素要先将数组中的元素取完

 

*/

import java.io.*;

class MyBufferedInputStream

{

       privateInputStream in;

       privatebyte[] by=new byte[1024];

       privateint count=0,pos=0;

       MyBufferedInputStream(InputStreamin)

       {

              this.in=in;

       }

 

       //自定义读方法,一次读一个字节

       public int myRead()throws IOException

       {

              //通过in对象读取硬盘上数据,并存储by中。

              //存储在数组中的数据被读取完,再通过in对象从硬盘上读取数据

              if(count==0)

              {

                     count=in.read(by);

                     if(count<0)//文件数据全部被读取出来了

                            return-1;

 

                     pos=0;//初始化指针

                     byteb=by[pos];

                     count--;//每被读一个字节,表示数组中的字节数少一个

                     pos++;//指针加1

                     returnb&255;//返回的byte类型提升为int类型,字节数增加,且高24位被补1,原字节数据改变。

                                          //通过与上255,主动将byte类型提升为int类型,将高24位补0,原字节数据不变。

                                          //而在输出字节流写入数据时,只写该int类型数据的最低8位。

              }

              elseif(count>0)//如果数组中的数据没被读取完,则继续读取

              {

                     byteb=by[pos];

 

                     count--;

                     pos++;

                     returnb&0xff;

              }

              return-1;

       }

       

       //自定义关闭资源方法

       publicvoid close()throws IOException

       {

              in.close();

       }

}

 

//测试自定义输入字节流缓冲区

class MyBufferedCopyMp3

{

       publicstatic void main(String[] args) 

       {

              longstart=System.currentTimeMillis();

              //利用字节流的缓冲区进行复制

              copy_2();

              longend=System.currentTimeMillis();

              System.out.println("复制共用时:"+(end-start)+"毫秒");

       }

       //使用字节流的缓冲区进行复制

       publicstatic void copy_2()

       {

              BufferedOutputStreambout=null;

              MyBufferedInputStreambin=null;

              try

              {

                     //关联复制文件输入流对象到缓冲区

                     bin=newMyBufferedInputStream(new FileInputStream("C:/Users/asus/Desktop/一样的月光.mp3"));

                     //指定文件粘贴位置的输出流对象到缓冲区

                     bout=newBufferedOutputStream(new FileOutputStream("C:/Users/asus/Desktop/一样的月光2.mp3"));

                     intby=0;

 

                     while((by=bin.myRead())!=-1)

                     {

                            bout.write(by);//将缓冲区中的数据写入指定文件中

                     }

              }

              catch(IOException e)

              {

                     thrownew RuntimeException("MP3复制失败");

              }

              finally

              {

                     try

                     {

                            if(bin!=null)

                                   bin.close();//关闭输入字节流

                     }

                     catch(IOException e)

                     {

                            thrownew RuntimeException("读取字节流关闭失败");

                     }

                     try

                     {

                            if(bout!=null)

                                   bout.close();//关闭输出字节流

                     }

                     catch(IOException e)

                     {

                            thrownew RuntimeException("写入字节流关闭失败");

                     }

              }

       }

}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: