黑马程序员Java学习日记(6)IO

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

1.IO概述:

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

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

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

4)流按操作数据分为两种

       1、字节流

       2、字符流

(5)流向分为:

       1、输入流

       2、输出流

2.IO流的常用基类:

1)字节流的抽象基类:

       1InputStream:字节读取流。

       2OutputStream:字节写入流。

(2)字符流的抽象基类:

       1Reader:字符读取流。

       2writer:字符写入流。

这两个基类中都是抽象方法,需要被子类实现。

 

注:由这四个类派生出的子类名称都是以其父类名作为子类名的后缀。

如:InputStream的子类 FileInputStream

如:Reader 的子类 FileReader

3.字符流:

(1)Writer中常用的方法:

writer() :将数据写入指定的文件中。

flash():数据一开始别没有直接写到文件中,而是在先写到了内存中的缓冲

       区中,需要用到flash方法,也就是刷新。

close():关闭流资源,在关闭之前会刷新一次。

 

代码例子:

需求:在硬盘上,创建一个文件并写入一些数据。

import java.io.*;

class FileWriterDemo1 

{

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

   {

          /*找到一个专门用于操作文件的writer子类对象,FileWriter

           创建一个FileWriter对象,该对象一被初始化就必须要明确

           被操作的文件。盘符有可能写错,所以需要抛异常*/

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

           //将数据写入文件中。

           fw.write("haha");

           fw.close(); //关闭流之前刷新了一次缓冲区。

     }

}

结果:

   当运行程序的时候,该文件会被创建到指定的目录下,在指定的目录下会产生一个指定名称的文件,如果该目录下已经有同名文件,那么将会覆盖原来的文件。

 

(2)那么为什么要关闭流呢?

   其实java本身是不能往windows里边写数据的,如window和Linux写数据的方式不同,所以java得靠系统内部的方式来完成内部的书写,所以java会调用系统中的内容,来完成数据的建立,那么这些调用方式都是在使用windows的资源,使用完了以后要释放出来,那么就需要做一个动作,就是关闭流,也就是close,close是先调用了一次flush,然后才把资源关掉。

 

(3)IO流异常的处理方式:

代码例子:

import java.io.*;

class  FileWriterDemo2

{

     public static void main(String[] args) 

     {

           FileWriter fw= null; //引用放在外边,各个语句都能调用到。

           try

           {

              /*这里盘符容易写错,如写了不存在的盘符 k所以会发生异常, 

              所以需要处理,所以要写到try语句中。*/

              fw = new  FileWriter("e:\\demo1.txt");

              fw.write("abcde");

            }

            catch (IOException  e)

            {

              System.out.println("catch:"+e.toString());

            }

            finally

            {

                 try

                {

                    /*当写了不存在的盘符,就会出现异常,文件对象就会创建

                    失败,那么w= nullnull能调用close,所以只有非null

                    的时候才能调用。*/

                    if(fw!=null)

                    fw.close();

               }

               catch (IOException  e)

               {

                  System.out.println("catch:"+e.toString());

               }

          }  

      }

}

发现:

   为什么不把fw.close();放到第一个try语句中?因为,加入文件对象建立好了,写了好多数据,但是内存不够了,就会抛异常了,然后就去catch语句中执行去了,从而执行部到close,因此资源还在内存中,所以close一定要执行,所以放在finally语句中。

 

(4)文件的续写:

当有了处理方式以后,那么我们就可以成功的在硬盘上创建文件,并写入数据,可是硬盘上已经有同名的文件了,并且文件中还有数据,那么想在这个已有文件的基础上进行文件的续写,该怎么做呢?

 

代码例子:

import java.io.*;

class  FileWriterDemo3

{

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

     {

          /*FileWriter的构造函数里面传递一个true参数,代表不覆盖已有的

          文件,并在已有文件的末尾处进行文件的续写。*/

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

          fw.write("haha");

          fw.close();

      }

}

 

(5)文本文件的读取方式(一):

代码例子:

import java.io.*;

class  FileWriterDemo3

{

     public static void main(String[] args) 

     {

        FileReader fr = null;

        try

        {

              /*用到了Rerder的子类FileReader,创建一个读取流对象,和指定名

              称的文件相关联。这里要保证该文件是已存在的,如果不存在,会 

              发生异常FileNotFoundExcrption*/

               fr =new FileReader("e:\\demo.txt");

              int ch = 0;

               //一次只读一个字符。

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

              {

                //因为read返回的是作为整数读取的字符,需要强转成字符。

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

               }

          }

         catch (IOException e)

         {

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

          }

         finally

         {

              try

              {

                 if(fr!=null)

                 fr.close();

               }

               catch (IOException w)

               {

                   throw new RuntimeException("关闭失败");

                }

             }

       }

}

(6)文本文件的读取方式(二):

代码例子:

import java.io.*;

class  FileWriterDemo4

{

      public static void main(String[] args) 

     {

            FileReader fr =null;

            try

            {

                  fr =new FileReader("e:\\demo.txt");

                  //定义一个字符数组,用于存放读到的字符。

                  char[] buf =new char[1024];

                  int num = 0;

                  //read返回的是读到字符的个数。

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

                  {

                     /*用字符串的形式打印数组,buf表示传进来的数组,0代表从0

                     标位开始读,num是取出字符的个数。*/

                   System.out.println(num+".."+new String(buf,0,num));

                   }

                }

               catch (IOException e)

               {

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

                }

                finally

                {

                     try

                    {

                       if(fr!=null)

                       fr.close();

                     }

                    catch (IOException w)

                    {

                          throw new RuntimeException("关闭失败");

                     }

                 }

          }

}

(7)复制文本文件:

要求:

   将e盘下的一个文本文件复制到d盘的一个文件中。

代码例子:

import java.io.*;

class  Copy

{

         public static void main(String[] args) 

         {

             copy();

         }

         //将读写过程封装到一个方法中。

         public static void copy()

         {

               FileWriter fw =null;

               FileReader fr =null;

               try

               {  

                    //创建写入流对象,在d盘创建一个文件。

                    fw=new FileWriter("d:\\copy.txt");

                    //创建读取流对象,与e盘文件相关联。

                    fr=new FileReader("e:\\javaio\\io11\\FileWriterDemo4.java");

                   /*此时数组还有一个作用,就是让FileReaderFileWriter

                    产生了联系,是一个中转站。*/

                    char[] ch =new char[1024];

                    int num=0;

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

                    {

                       //读一个,写一个。

                       fw.write(ch,0,num);

                    }

               }

              catch (IOException e)

             {

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

             }

             finally

             {

                    if(fr!=null)

                    try

                    {

                     fr.close();

                    }

                    catch (IOException q)

                    {

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

                    }

                   if(fw!=null)

                   try

                   {

                      fw.close();

                   }

                  catch (IOException w)

                  {

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

                   }

             }

       }

}

 

(8)字符流缓冲区:

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

    2、对应的类有:1BufferedWriter

                               2BufferedReader

    3、缓冲区要结合流才可以使用。

    4、在流的基础上对流的功能进行增强。

    5、字符流缓冲区提供了一个跨平台的换行符:newLine

    6BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数组和字符串的高效写入。

    7、BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符,数组和行的高效读取。

    8、可以指定缓冲区的大小,或者接受默认的大小,一般情况下默认值足够大了。

(9)用缓冲区复制文本文件:

需求:通过缓冲区复制一个.java文件。

代码例子:

import java.io.*;

class  CopyDemo

{

     public static void main(String[] args)  

     {

        BufferedWriter bw= null;

        BufferedReader br= null;

        try

        {

           /*创建一个写入流对象,为了提高效率加入缓冲技术,将字符写入流

            作为参数传递给缓冲区的构造函数。*/

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

           /*创建一个读取流对象,并与文件相关,为了提高效率加入缓冲技术,

           将字符读取流作为参数传递给缓冲区的构造函数。*/

           Br = new  BufferedReader(new FileReader(

           "e:\\lianxidaima\\javaio\\day192\\BufferedReaderDemo.java")); 

          //变量也是中转站,使BufferedReaderBufferedWriter产生联系。 

           String line=null;

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

           {

                bw.write(line);

                //一次读一行。

               bw.newLine();

               //字符流缓冲区需要刷新。

               bw.flush();

            }

         }

         catch (IOException e)

         {

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

          }

        finally

        {

             if(bw!=null)

              try

             {

                bw.close();

              }

             catch (IOException q)

             {

               throw new RuntimeException("关闭失败");

              }

             if(br!=null)

             try

             {

                br.close();

             }

             catch (IOException w)

             {

                throw new RuntimeException("关闭失败");

             }

        }

    }

}

 

(10)装饰设计模式:

什么是装饰设计模式:

  当想要把已有的功能进行增强时,可以定义一个类,将已有对象传入,基于已有对象里面的功能,并提供加强功能,那么这个自定义的类称为装饰类。

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

 

(11)装饰和继承的区别:

     1、装饰是为了优化以前的体系而存在的。使的以前的体系一优化完成一个更简单的方式,更具有扩展性。

     2、装饰模式比继承更加灵活,避免了继承体系的复杂,而且降低了类与类之间的关系。

     3、因为装饰类增强已有对象具备的功能和已有对象的功能是相同的,只不过是提供了更强的功能,所以装饰类和

          被装饰类通常都是属于一个体系中的。

     4、装饰类同属于同一个接口或者同一个类,从继承结构变为组合结构。

 

4.字节流:

需求:复制一个图片。

代码例子:

import java.io.*;

class  CopyStream

{

     public static void main(String[] args) 

     {

        FileInputStream fis=null;

        FileOutputStream fos=null;

        try

       {

             //创建一个字节写入流。

             fos=new FileOutputStream("2.jpg");

            //创建一个字节读取流与文件相关联。

             fis=new FileInputStream("e:\\3.jpg");

             //定义一个缓冲区,长度足够大。

            byte[] b=new byte[1024*10];

            int line =0;

             while((line=fis.read(b))!=-1)

             {

                //字节流不需要刷新。

               fos.write(b,0,line);

             }

        }

       catch (IOException e)

       {

           throw new RuntimeException("复制文件失败");

       }

       finally

       {

             try

             {

                if(fis!=null)

                fis.close();

             }

            catch (IOException q)

            {

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

             }

             try

             {

                if(fos!=null)

                fos.close();

              }

             catch (IOException w)

             {

                 throw new RuntimeException("关闭输出流失败");

              }

          }

      }

}

(1)字节流的缓冲区:

import java.io.*;

class CopyBufferedStream 

{

         public static void main(String[] args) 

        {

             BufferedInputStream bufis = null;

             BufferedOutputStream bufos = null;

             try

            {

                 bufis = new BufferedInputStream(new FileInputStream("e:\\1.mp3"));

                 bufos = new BufferedOutputStream(new FileOutputStream("e:\\0.mp3"));            

                 int by = 0;

                 while((by=bufis.read())!=-1)

                 {

                     bufos.write(by);

                 }

            }

           catch (IOException e)

           {

               throw new RuntimeException("复制文件失败");

           }

          finally

          {

               try

               {

                   if(bufis!=null)

                    bufis.close();

                }

               catch (IOException q)

               {

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

                }

               try

               {

                  if(bufos!=null)

                  bufos.close();

                }

                catch (IOException w)

                {

                   throw new RuntimeException("关闭输出流失败");

                }

            }

       }

}

 

(2)读取键盘录入:

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

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

import java.io.*;

class  Readin

{

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

    {   

            //获取键盘录入。

            InputStream in=System.in;

           //将键盘录入传给字节读取流。

           InputStreamReader isr=new InputStreamReader(in);

           //需要提高效率,用到字节流缓冲区。

           BufferedReader br =new BufferedReader(isr);

           String line =null;

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

           {

               //录入小写,返回大写。

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

           }

              br.close();

       }

}

 

(3)读取转换流:

import java.io.*;

class TransStreamDemo 

{

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

       {

              //获取键盘录入对象。

              InputStream in = System.in;

              //将字节流对象转成字符流对象。

             InputStreamReader isr = new InputStreamReader(in);

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

             使用BufferedReader*/

             BufferedReader bufr = new BufferedReader(isr);

             String line= null;

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

             {

                 //定义一个结束标记,输入over就结束程序。

                 if("over".equals(line))

                      break;

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

             }

              bufr.close();

       }

}

(4)写入转换流:

import java.io.*;

class TransStreamDemo2 

{

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

     {

          //获取键盘录入对象。

          InputStream in = System.in;

          //将字节流对象转成字符流对象。

          InputStreamReader isr = new InputStreamReader(in);

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

          使用BufferedReader*/

          BufferedReader bufr = new BufferedReader(isr);

  

          //获取键盘输出对象。

          OutputStream out = System.out;

          //将字节流对象转成字符流对象。

          OutputStreamWriter osw = new OutputStreamWriter(out);

          //为了提高效率使用BufferedWriter

   

         BufferedWriter bufw = new BufferedWriter(osw);

         String line= null;

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

        {

           //定义一个结束标记,输入over就结束程序。

           if("over".equals(line))

               break;

             //字符流对象可以直接操作字符串。

            bufw.write(line.toUpperCase());

            bufw.newLine();

            bufw.flush();

         }

         bufr.close();

         bufw.close();

      }

}

(5)键盘录入的常见写法:

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

 

流操作的基本规律:

通过3个明确来完成:

     1、明确源和目的。

          源:输入流。InputStream   Reader   System.in 

          目的:输出流。OutputStream  Writer  System.out

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

          如果是纯文本就使用字符流。

          如果不是就使用字节流。

     3、当体系明确后,再明确使用哪个具体的对象。通过设备来进行区分:

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

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

5.File

   1、用来将文件或者文件夹的属性信息进行操作。

   2、方便对文件与文件夹的属性信息进行操作。

   3File对象可以作为参数传递给流的构造函数。

   4、了解File类中的常用方法。

   5、这个类的出现弥补了流的不足,流对象能操作文件,但是它不能操作文件夹,文件的属性信息不能操作。

   6、想要操作数据封装成文件的信息必须用到File对象。

 

(1)File类的常用方法:

 1、创建:

             1.1boolean createNewFile(); 

           特点:在指定位置创建文件,如果该文件已经存在,则不创建返回flase,和输出流不一样,输出流对象一建立

            就创建文件,而且文件如果存在,可以覆盖。

 

           1.2boolean mkdir(); 创建文件夹,只能创建一级目录,创建成功就

           返回true,否则返回flase

           1.3boolean mkdirs(); 创建多级文件夹,创建成功就返回true,否则返回flase

 

2、删除:

             2.1boolean delete();   删除文件。

         2. 2void deleteonExit(); 在退出程序时删除指定文件。

 

3、判断:

         3.1boolean canExecute(); 这个文件是否可执行,如果有这个文件就

              true,没有就返回flase

         3.2boolean exists(); 这个文件是否存在,有就返回True,没有就返

              回flase

         3.3boolean isDirectory(); 判断是否是目录,前提是文件或目录存在。

         3.4boolean isFile();      判断是否是文件,前提是文件或目录存在。

         3.5boolean Hidden();    判断是否是隐藏文件。

         3.6boolean isAbsolute(); 判断是否是绝对路径,无论文件是否存在,

              都可以判断。

 

4、获取信息:

             4.1String getName(); 获取名称。

             4.2String getPath();  获取路径,封装什么路径就获取什路径。

             4.3String getParent(); 获取父目录,如果没有指定的绝对路径,

                  它就返回null,如果相对路径中有上一层目录,那么该目

                  录就是返回的结果。  

             4.4String getAbsolutePath(); 获取绝对路径,无论你封装的是

                   相对路径还是绝对路径,它都取绝对路径。

             4.5long lastModified(); 文件最后一次被修改的时间。

             4.6long length(); 文件的大小。

 

代码例子:

文件列表一:

     1Static File[] listRoots(); 列出可用的文件系统根,操作的是共享数据,不

        操作特有数据,所以不用写参数。这个方法是静态方法,返回的是数组。

     代码例子:

      import java.io.*;

      class FileDemo 

      {

            public static void main(String[] args) 

            {

              ListRootsDemo();

            }

            public static void listRootsDemo()

            {

                 File[] files = File.listRoots();

                 //高级for循环遍历数组。

                  for(File f:files)

                  {

                         //打印的是主机里面的有效盘符。

                        System.out.println(f);

                  }

             }

     }

     注意:这里不可以使用length()方法,获取盘符所谓的长度没有意义。

 

     2String[] list(); 返回一个字符串数组,这些字符串指定路径表示的目录中

        的文件和目录。

     代码例子:

     import java.io.*;

     class FileDemo2 

     {

         public static void main(String[] args) 

         {

            listDemo();

         }

        public static void listDemo()

        {

            File f = new File("c:\\");

            String[] names = f.list();

            for(String name:names)

            {

                /*打印的结果是当前目录下c盘的所有文件名和目录,包含隐藏文*/ 

                System.out.println(name);

             }

         }

     }

如果改成File f = new File("c:\\abc.txt"); 打印的结果是空指针异常。因为当list

方法所属的对象是一个文件的时候,因为文件里面没有东西,所以返回的数组就为空,为空了就不能被对象指向并且遍历了,里面调用了length属性。

注意:调用list方法的file对象必须是封装了一个目录,而且该目录必须存在。

 

文件列表二:

FileenameFilter 接口,实现此接口的类实例可用于过滤器文件名。它里面只有

一个方法,boolean accept(File dir, String name); 

          1、过滤哪一个目录中的文件,要先确定目录,目录是未知的。

          2、要过滤目录中的哪一个文件,也是未知的。

所以定义两个参数,符合要求为true,不符合要求为flase

代码例子:

import java.io.*;

class FileDemo3 

{

      public static void main(String[] args) 

      {

            //封装一个已有的目录。

            File dir = new File("e:\\lianxidaima\\javaio");

            //用匿名内部类的形式创建子类对象。

           String[] arr =dir.list(new FilenameFilter()

           {

                //复写FilenameFilter接口方法。

               public boolean accept(File dir,String name)

              {

                  return true;

              }

         });

             //打印的是这个目录下项目的个数。

             System.out.println(arr.length);

             for(String name:arr)

             {

               //打印的结果为这个目录下的所有的文件名。

              System.out.println(name);

              }

       }

}

如果返回的是flase的话,打印的长度为零。原来list方法它在依据new 这个对象的accept方法的返回值类判定这个文件是不是需要的文件。当为flase时,上边指定的目录就是要被过滤的目录,dir就是这个目录,打印dir,结果就是这个目录。Name是这个目录下的所有文件名,如果想要扩展名是.java的文件,只要判断name就行。例如:return name.endswith(".java"); 打印的结果都是.java的文件名。

 

File[] listFiles() 

代码例子:

import java.io.*;

class FileDemo4 

{

    public static void main(String[] args) 

    {

      File dir = new File("c:\\");

      File[] files = dir.listFiles();

      for(File f:files)

      {

          //打印结果是该路径下文件的名称和文件的大小,不能获取文件夹。

          System.out.println(f.getName()+".."+f.length());

       }

    }

}

总结:

String[] list()方法对应的过滤器为:String[] list(FilenameFilter filter)

File[] listFiles()方法对应的过滤器为:1File[] listFiles(FileFilter filter)

                                                           2File[] listFiles(FilenameFilter filter)

(2)list与listFiles的区别:

List这个方法它返回的是当前目录下的文件以及文件夹名称,只能获取名称。

listFiles这个方法返回的是当前目录下的文件以及文件夹的对象,可以通过getName()来获取名称,也可以通过length()来获取大小,也可以通过getPath()来获取路径。listFiles在开发的时候比较常用。

ListlistFile只能列出当前目录下的所有内容,如果目录下还有目录,该怎么列出呢?

列出目录下所有内容——递归

列出指定目录下文件或者文件夹,包含子目录中的内容,也就是列出指定目录下所有内容。

什么是递归:

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可,在列出的过程中出现的还是目录的话,还可以再次调用本功能,也就是函数自身调用自身,这种表现形式,或者编程手法,称为递归。

 

代码例子:

import java.io.*;

class FileDemo5 

{

       public static void main(String[] args) 

      {

         File dir = new File("e:\\lianxidaima\\javaio");

         showDir(dir);

      }

      public static void showDir(File dir)

      {

             //用来列出目录名。

             System.out.println(dir);

             //列出文件。

             File[] files = dir.listFiles();

             for(int x=0;x<files.length;x++)

             {

                  //判断列出的文件是否是目录,如果是就再调用函数列出来。

                  if(files[x].isDirectory())

                     //调用自身功能再列一遍。

                      showDir(files[x]);

                      //如果不是就打印列出的文件。

                   else

                     System.out.println(files[x]);

              }

        }

}

递归要注意:1、限定条件。

                      2、要注意递归的次数,尽量避免内存溢出。

解释:例 public static void method()

         {

           //调用自身函数。

           method();

         }

这也是一个递归,但是它停不下来,所以要限定条件。

 

练习:

列出目录下所有内容——带层次。

代码例子:

 import java.io.*;

class FileDemo6 

{

     public static void main(String[] args) 

     {

         File dir =new File("e:\\lianxidaima");

         showDir(dir,0);

     }

    public static String getLevel(int level)

    {

       StringBuilder sb = new StringBuilder();

       for(int x=0;x<level;x++)

       {

           sb.append("");

       }

        return sb.toString();

     } 

    public static void showDir(File dir,int level)

    {

         System.out.println(getLevel(level)+dir.getName());

         level++;

         File[] files = dir.listFiles();

         for(int x=0;x<files.length;x++)

         {

              if(files[x].isDirectory())

                  showDir(files[x],level);

              else

                 System.out.println(getLevel(level)+files[x]);

          }

      }

}

6.Properties概述:

     1、Propertieshashtable的子类,它具备map集合的特点,而且它里面存储的键值对都是字符串。

     2、是集合中和IO技术想结合的集合容器。

 

(1)Properties对象的特点:

     1、可以用于键值对形式的配置文件,不仅可以操作键值对,而且可以操作硬盘的键值对信息。

     2、在加载数据时,需要数据有固定的格式:键=值。

 

代码例子:

import java.io.*;

import java.util.*;

class  PropertiesDemo

{

      public static void main(String[] args) 

      {

         setAndGet();

       }

      public static void setAndGet()

      {

            //创建一个集合对象。

           Properties prop = new Properties();

           //设置键值对。

           prop.setProperty("zhangsan","30");

           prop.setProperty("lisi","35");

          System.out.println(prop);

 

          //获取值。

          String value = prop.getProperty("lisi");

         System.out.println(value);

         //修改值。

         prop.setProperty("lisi","89");

         //遍历集合中的元素。

        Set<String> names = prop.stringPropertyNames();

        for(String s:names)

        {

             //打印键和对应的值。

           System.out.println(s+"..."+prop.getProperty(s));

         }

      }

}

 

Properties存储配置文件:

import java.io.*;

import java.util.*;

class PropertiesDemo3 

{

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

       {

            loadDemo();

       }

      public static void loadDemo()throws IOException

      {

          Properties prop = new Properties();

          //与文件相关联。

          FileInputStream fis = new FileInputStream("e:\\b.txt");

          //将流中的数据加载进集合。

          prop.load(fis);

          //修改值。

          prop.setProperty("wangwu","40");

         //将值存进硬盘中。

         FileOutputStream fos = new FileOutputStream("e:\\b.txt");

         prop.store(fos,"haha");

         prop.list(System.out);

      }

}

 

7.打印流:

(1)PrintWriter

(2)PrintStream:

他输出流添加了功能,使它们能够方便地打印各种数据值表现形式。

该流提供了打印方法,可以将各种数据类型的数据都按原样打印。

PrintWriter:

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

   1file对象,类型是File

   2、字符串路径,类型是String

   3、字节输出流,类型是OutputStream

   4、字符输出流,类型是Writer

PrintStream:

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

   1file对象,类型是File

   2、字符串路径,类型是String

   3、字节输出流,类型是OutputStream

  

代码例子:

import java.io.*;

class  PrintWriterDemo

{

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

     {

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

         PrintWriter out = new PrintWriter(System.out,true);

         String line = null;

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

          {

              if("over".equals(line))

                  break;

              out.println(line.toUpperCase());

           }

            bufr.close();

            out.close();

       }

}

 

8.序列流:

SequenceInputStream:对多个流进行合并。

就是把多个流变成一个流。

代码例子:

import java.io.*;

import java.util.*;

class SequenceDemo 

{

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

    {

        Vector<FileInputStream> v = new Vector<FileInputStream>();

        v.add(new FileInputStream("e:\\1.txt"));

        v.add(new FileInputStream("e:\\2.txt"));

        v.add(new FileInputStream("e:\\3.txt"));

        //3个流对象添加倒集合中。

        Enumeration<FileInputStream> en = v.elements();

        //把上边的3个流对象变成一个流对象。

 

        SequenceInputStream sis = new SequenceInputStream(en);

        FileOutputStream fos = new FileOutputStream("e:\\4.txt");

        byte[] buf = new byte[1024];

        int len = 0;

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

         {

              fos.write(buf,0,len);

         }

         fos.close();

         sis.close();

      }

}

切割文件:

  FileInputStream fis =  new FileInputStream("c:\\1.bmp");

  FileOutputStream fos = null;

  byte[] buf = new byte[1024*1024];

  int len = 0;

  int count = 1;

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

  {

     fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");

     fos.write(buf,0,len);

     fos.close();

   }

   fis.close();

9.对象的序列化:

操作对象:1ObjectInputStream

                  2ObjectOutputStream

它们可以操作对象的流,被操作的对象需要实现Serializable接口。

序列化的作用:

以为对象中要存储一些数据,如果在对内存中的话,程序结束以后,对象也就回收了,所以把对象存在硬盘上,如果需要用到里面的数据的话,只要读出来就可以。把对象存在硬盘上叫做对象的持久化存储。

 

通过ObjectInputStream读,就必须通过ObjectOutputStream写,它们是相对的。

ObjectOutputStream(OutputStream out)在构造的时候必须传一个目的,它的功能是让流和被操作的对象相结合。

 

注意:静态是不能被序列化的。

 

10.管道流:

(1)PipedInputStream

(2)PipedOutputStream

输入和输出可以直接进行比较,通过结合线程使用。

代码例子:

class Read implements Runnable

{

    private PipedInputStream in;

    Read(PipedInputStream in)

    {

        this.in = in;

    }

    public void run()

    {

       try

      {

         byte[] buf = new byte[1024];

        System.out.println("读取前,,没有数据阻塞");

        int len = in.read(buf);

        System.out.println("读到数据,,阻塞结束");

        String s= new String(buf,0,len);

        System.out.println(s);

        in.close();

      }

      catch (IOException e)

     {

      throw new RuntimeException("管道读取流失败");

      }

   }

 }

 

class Write implements Runnable

{

       private PipedOutputStream out;

       Write (PipedOutputStream out)

      {

           this.out = out;

      }

      public void run()

      {

           try

          {

             System.out.println("开始写入数据,等待6秒后。");

             Thread.sleep(6000);

             out.write("piped lai la".getBytes());

             out.close();

            }

           catch (Exception e)

           {

              throw new RuntimeException("管道输出流失败");

            }

         }

   }

 

 class  PipedStreamDemo

 {

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

      {

           PipedInputStream in = new PipedInputStream();

           PipedOutputStream out = new PipedOutputStream();

           in.connect(out);

           Read r = new Read(in);

           Write w = new Write(out);

           new Thread(r).start();

           new Thread(w).start();

       }

  }

 

11.随机访问文件:

RandomAccessFile:是一个单独的工具类,只继承Objict

      1、随机访问文件,自身具备读写的方法。

      2、通过skipBytes(int x),seek(int x)来达到随机访问。

 

(2)RandomAccessFile的特点:

      1、该类不是IO体系中的子类,而是直接继承Objict

      2、是IO包中的成员,因为它具备读和写的功能,它在对象内部

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

      3、可以通过getFilePointer来获取指针的位置,同时可以通过seek改变

        指针的位置。

      4、内部封装了字节输入流和字节输出流。

(3)RandomAccessFile的不足:

   该类只能操作文件,而且操作文件还有模式。

 

(4)DataStream:用于操作基本数据类型。

     1DataInputStream

     2DataOutputStream

 

(5)ByteArrayStream:用于操作字节数组的流对象。

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

    2、ByteArrayOutputStream在构造的时候,不用定义数据目的,因为对象中已经封装了可变长度的字节数组。

因为这两个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭。

12.字符编码:

编码:字符串变成字节数组。

解码:字节数组变成字符串。

 

String 变成byte[];通过str.getBytes(charSetName);

byte[]变成String;通过 new String(byte[],charSetName)

数组 变成String:通过Arrays.toString();

默认的是GBK编码表。

 

 

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值