黑马程序员_Java基础_IO流(三)_20

来源:互联网 发布:我知女人心大雷小雷 编辑:程序博客网 时间:2024/05/22 15:11

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

 

导读:导读:File概述、File对象功能-创建、删除、判断获取,File对象功能-文件列表,列出目录下所有内容-递归、带层次,删除带内容的目录,创建java文件列表,Properties简述、存取、存取配置文件,Properties练习,PrintWriter,合并流,切割文件

 

1、IO流(File概述、File对象功能-创建、删除、判断获取)

  • Java中对文件事物进行了描述,这样的描述类,我们称之为File类。

Ø 用来将文件或者文件夹封装成对象
Ø 方便对文件与文件夹的属性信息进行操作。(流对象能操作文件,但不能操作文件夹,它不能够操作文件的属性信息。流只能操作数据)
Ø File对象可以作为参数传递给流的构造函数。

Ø 了解File类中的常用方法。

  • Java.io中的File类,是文件和目录路径名的抽象表示形式。
  • 字段:

static Stringseparator:目录分隔符。(与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串)

  • 构造方法:

Ø File(Stringpathname):通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。

Ø File(Stringparent, String child):将目录和文件名,都作为参数传递。

Ø File(File parent,String child):将目录封装成一个对象。

/*

  • File类常见方法:

1,创建。

 Ø boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。(调用了底层的资源,所以会抛出IOException)

Ø static File createTempFile(String prefix,String suffix):在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。

Ø static File createTempFile(String prefix,String suffix, File directory):在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。                                         

Ø boolean mkdir():创建文件夹。(只能创建一级目录)

Ø boolean mkdirs():创建多级文件夹。

2,删除。

Ø boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。(如果必须要删的话,若放在finally中,可以删但是有可能删不掉)

Ø void deleteOnExit();在程序退出时删除指定文件。

3,判断。

Ø boolean exists() :文件是否存在.

Ø isFile():

Ø isDirectory();

Ø isHidden(); (有些文件是访问不了的,用流,如C盘的系统卷标目录,system打头的,尽量不要访问硬盘中隐藏的文件。Java有什么特点,只要是文件我全要不和管是隐藏不隐藏。所以要判断一下,只拿非隐藏的。)

       Ø isAbsolute():判断文件是否是绝对路径,即使文件不存在也会判断。

Ø boolean canRead():测试应用程序是否可以读取此抽象路径名表示的文件。

Ø boolean canWrite():测试应用程序是否可以修改此抽象路径名表示的文件。

Ø int compareTo(File pathname):按字母顺序比较两个抽象路径名。

4,获取信息。(返回路径一定是字符串)

Ø getName():

Ø getPath():

Ø getParent():

Ø getAbsolutePath():与相比File getAbsoluteFile()返回的也是绝对路径,但它把绝对路径封装成了对象。字符串和对象之间是可以互相转化的,把字符串new一下,就要转化为对象了。把File对象toString一下,就变为字符串了。

Ø long lastModified():最后一次修改的时间。(应用:判断一下,是不是上一次加载后,我修改完后的那个文件。因为别人也有可能会修改这个文件。时间相等说明没有被修改过,时候不等说明被修改过。)

Ø long length():获取文件的大小

*/

  • import java.io.*;

class FileDemo

{

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

       {

              method_5();

       }

       public static void method_5()

       {

              File f1 = newFile("c:\\Test.java");

              File f2 = new File("d:\\hahah.java");

              sop("rename:"+f2.renameTo(f1)); //renameTo();重命名

       }

       public static void method_4()

       {

              File f = newFile("file.txt");

              sop("path:"+f.getPath());

              sop("abspath:"+f.getAbsolutePath()); //无论你封装的是绝对的还是相对的,我拿到的都是绝对的。在相对文件的前面加上对应的父目录。虽然文件是不存在的,但是目录可以获取到。

              sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。如果相对路径中有上一层目录那么该目录就是返回结果。

       }

       public static void method_3()throwsIOException

       {

              File f = newFile("d:\\java1223\\day20\\file2.txt");

              //f.createNewFile();

              //f.mkdir();

              //记住在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在。

              //通过exists判断。(当发现不是文件不是目录的时候会崩溃掉的)

              sop("dir:"+f.isDirectory());

              sop("file:"+f.isFile());

              sop(f.isAbsolute()); //在这里返回结果为true,虽然没有创建文件。

       }

       public static void method_2()

       {

              File f = newFile("file.txt");

              //sop("exists:"+f.exists());

              //sop("execute:"+f.canExecute()); //只要文件可执行,只要掉上runtime对象,可以把本机里面所有能执行的文件全部打开。

              //创建文件夹

              File dir = newFile("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

              sop("mkdir:"+dir.mkdirs()); //创建多级目录

       }

       public static void method_1()throwsIOException

       {

              File f = newFile("file.txt");

              //sop("create:"+f.createNewFile());

              //sop("delete:"+f.delete()); //如果在执行操作代码的时候发生了异常,则执行不到这条语句。可以在new File写上这句话:f.deleteOnExit();

       }

       //创建File对象

       public static void consMethod()

       {

              //将a.txt封装成file对象。可以将已有的和未出现的文件或者文件夹封装成对象。

              File f1 = newFile("a.txt");

              //第二种方式:c:\\abc指的是你目录,b.txt指的是目录中的文件名。将目录和文件分开成两个参数来传递

              File f2 = newFile("c:\\abc","b.txt");

              //File f2 = newFile("c:\\abc",str); //如果写成这样的话,操作的文件是可以变化的。一般写字符串常见一些,因为它简单。

   //第三种方式:和第二种方式是一样的

              File d = newFile("c:\\abc"); //中间有目录分隔符。

              Filef3 = new File(d,"c.txt");

              sop("f1:"+f1); //打印出来只有相对路径。f1中封装的是什么,它打印的就是什么。

              sop("f2:"+f2); //打印出来,显示的是文件的绝对路径。

              sop("f3:"+f3);

              File f4 = newFile("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");

//File.separator代表的是跨平台的分隔符。到了Linux系统下也能用

       }

       public static void sop(Object obj)

       {

              System.out.println(obj);

       }

}

  • 文件覆盖的原理就是先判断,文件.exist,如果文件存在的话,先把文件删了再建一个

 

2、IO流(File对象功能-文件列表)

  • String[] list():返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
  • String[]list(FilenameFilter filter):返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。 java.io中的接口 FilenameFilter只有一个方法:booleanaccept(File dir, String name),测试指定文件是否应该包含在某一文件列表中。
  • File[] listFiles():真实开发中这个好一些。和String[] list()相比,它返回的是当前文件夹下的目录及文件的对象。对象可以通过getName()获取名称,可以通过length()获取大小,可以通过getPath()获取路径。
  • File[]listFiles(FileFilter filter):返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
  • static File[]listRoots():列出可用的文件系统根。
  • import java.io.*;

class  FileDemo2

{

       public static void main(String[] args)

       {

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

              File[] files = dir.listFiles(); // String[] list(FilenameFilter filter) 文件名过滤,我想要文件夹下所有的java文件,其他的所有文件都不要。

              for(File f : files)

              {

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

              }

       }

       public static void listDemo_2()

       {

              File dir = newFile("d:\\java1223\\day18");

//FileternameFileter(),它是一个接口类型,只有一个方法,可以传进来一个匿名内部类。List()方法根据你指定的accept()方法的返回值来判断你是不是要过滤文件。如果返回true说明这些文件,都是符合条件的,如果返回false说明这些文件都被过滤掉了。

              String[] arr = dir.list(newFilenameFilter() 

              {

                     public boolean accept(Filedir,String name)

                     {

                            //System.out.println("dir:"+dir+"....name::"+name);

                            /*

                            if(name.endsWith(".bmp"))

                                   return true;

                            else

                            return false;

                            */

                            returnname.endsWith(".bmp"); //只需要对于名字做一下判断就可以了。

                     }

              });

              System.out.println("len:"+arr.length);

              for(String name : arr)

              {

                     System.out.println(name);

              }

       }

       public static void listDemo()

       {

              File f = newFile("c:\\abc.txt"); //如果这里不是一个目录,误写成了一个文件名称,数组为空,会抛出空指针异常。

              String[] names = f.list();//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。

              for(String name : names)

              {

                     System.out.println(name);//打印了指定目录下的文件及文件夹的名称,它打印的结果里面,有一些是隐藏的。

              }

       }

       public static void listRootsDemo()

       {

              File[] files = File.listRoots(); //可以列出来我们机器中的有效的盘符。listRoots它是一个静态的方法,它不操作具体的特有的数据。返中一个File[]

              for(File f : files)

              {

                     System.out.println(f);

              }

       }

}

 

3、IO流(列出目录下所有内容-递归、带层次)

  • 能不能拿当前目录下所有文件,包括子目录中的文件呢?
  • 列出指定目录下文件或者文件夹,包含子目录中的内容。也就是列出指定目录下所有内容。

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

  • 递归要注意:

1,限定条件。

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

  • import java.io.*;

class FileDemo3

{

       public static void main(String[] args)

       {

              File dir = newFile("d:\\testdir");

              //showDir(dir,0);

              //toBin(6);

              //int n = getSum(8000); //不断的递规,在内存的栈中会有很多个没有运行完的方法所需要的空间,超出了内存的范围,发生内存溢出。

              //System.out.println("n="+n);

              System.out.println(dir.delete());

       }

       public static String getLevel(int level)

       {

              StringBuilder sb = newStringBuilder();

              sb.append("|--");

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

              {

                     //sb.append("|--");

                     sb.insert(0,"|  ");

              }

              return sb.toString();

       }

       public static void showDir(File dir,intlevel)

       {

              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]);

              }

       }

       public static int getSum(int n)

       {

              if(n==1)

                     return 1;

              return n+getSum(n-1);

       }

       public static void toBin(int num)

       {

              if(num>0)

              {

                     toBin(num/2);

                     System.out.println(num%2);

              }

       }

}

 

4、IO流(删除带内容的目录)

  • 删除一个带内容的目录。
  • 删除原理:在window中,删除目录从里面往外删除的。

既然是从里往外删除。就需要用到递归。

  • import java.io.*;

class  RemoveDir

{

       public static void main(String[] args)

       {

              File dir = newFile("d:\\testdir");

              removeDir(dir);

       }

       public static void removeDir(File dir)

       {

              File[] files = dir.listFiles();

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

              {

                     if(files[x].isDirectory())

                            removeDir(files[x]);

                     else

                            System.out.println(files[x].toString()+":-file-:"+files[x].delete());

              }

              System.out.println(dir+"::dir::"+dir.delete());

       }

}

如果结果中还有false的话,这个文件夹或者文件还被误删除过。它本身里面还有东西可是你误删除了它一次,或者已经删光了你又删除了一次。

  • 系统中有一个卷标目录,你要是删的话,是删不掉的。它里面有一些隐藏的目录,java是无法访问的,无法访问java就无法去删。无法去删会导致返回来的files这个数组为空,会出现空指针异常。系统中有些文件,虽然看起来是一个文件,其实是一个目录,或者看起来是一个文件,其实是一个目录。你一访问也会出现空指针异常。
  • 遍历的时候最好判断一下dir.exist(),避开隐藏的文件。删除的时候不管那么多了全干掉,不让删算了,系统文件不让删。

 

5、IO流(创建java文件列表)

练习

将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。建立一个java文件列表文件。

思路:

1,对指定的目录进行递归。

2,获取递归过程所有的java文件的路径。

3,将这些路径存储到集合中。

4,将集合中的数据写入到一个文件中。

import java.io.*;

importjava.util.*;

class  JavaFileList

{

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

       {

              File dir = newFile("d:\\java1223");

              List<File> list = newArrayList<File>();

              fileToList(dir,list);

              //System.out.println(list.size());

              File file = newFile(dir,"javalist.txt");

              writeToFile(list,file.toString());

       }

       public static void fileToList(Filedir,List<File> list)

       {

              File[] files = dir.listFiles();

              for(File file : files)

              {

                     if(file.isDirectory())

                            fileToList(file,list);

                     else

                     {

                            if(file.getName().endsWith(".java"))

                                   list.add(file);

                     }

              }

       }

       public static voidwriteToFile(List<File> list,String javaListFile)throws IOException

       {

              BufferedWriter bufw =  null;

              try

              {

                     bufw = newBufferedWriter(new FileWriter(javaListFile)); //FileWriter中不仅可以传字符串,还可以传File对象。可以互相转化。

                     for(File f : list)

                     {

                            String path =f.getAbsolutePath();

                            bufw.write(path);

                            bufw.newLine();

                            bufw.flush();

                     }

              }

              catch (IOException e)

              {

                     throw e; //不抛的话,这里要用RunTimeException(),停掉

              }

              finally

              {

                     try

                     {

                            if(bufw!=null)

                                   bufw.close();

                     }

                     catch (IOException e)

                     {

                            throw e;

                     }

              }

       }

}

 

6、IO流(Properties简述、存取、存取配置文件)

  • Properties是hashtable的子类。也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。是集合中和IO技术相结合的集合容器。该对象的特点:可以用于键值对形式的配置文件。那么在加载数据时,需要数据有固定格式:键=值。(Properties,不仅可以操作键值对,还可以操作硬盘上的键值对信息)

ØString getProperty(String key)

          用指定的键在此属性列表中搜索属性。

ØObject setProperty(String key, String value)

          调用 Hashtable的方法 put。

Øvoid list(PrintStream out)

          将属性列表输出到指定的输出流。

Øvoid list(PrintWriter out)

          将属性列表输出到指定的输出流。

Øvoid load(InputStream inStream)

          从输入流中读取属性列表(键和元素对)。

  • 练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。void load(Reader reader):加载字符流是1.6版本之后才有的。

          按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。

Øvoid store(OutputStreamout, String comments):comments是注释信息爱加不加。

ØSet<String>stringPropertyNames():遍历集合,返回的是一个set集合

  • 练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。import java.io.*;

import java.util.*;

classPropertiesDemo

{

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

       {

              //method_1();

              loadDemo();

       }

       public static void loadDemo() throwsIOException

       {

              Properties prop = newProperties();

              FileInputStream fis = newFileInputStream("info.txt");

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

              prop.load(fis);

              prop.setProperty("wangwu","39");//将wang的年龄修改为39岁(改变的是内存的结果,没有文件中存)

              FileOutputStream fos = newFileOutputStream("info.txt");

              prop.store(fos,"haha"); //将内存中的结果存到一个流当中,并存到一个文件上。haha在记事本中打开,第一行显示为“#haha”不会被Properties所加载。

       //     System.out.println(prop);

              prop.list(System.out);

              fos.close();

              fis.close();

       }

       //演示,如何将流中的数据存储到集合中。

       //想要将info.txt中键值数据存到集合中进行操作。

       /*

  思路:

              1,用一个流和info.txt文件关联。

              2,读取一行数据,将该行数据用"="进行切割。

              3,等号左边作为键,右边作为值。存入到Properties集合中即可。

       */

       public static void method_1() throwsIOException

       {

              BufferedReader bufr = newBufferedReader(new FileReader("info.txt"));

              String line = null;

              Properties prop = newProperties();

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

              {

                     String[] arr =line.split("=");

                     ///System.out.println(arr[0]+"...."+arr[1]);

                     prop.setProperty(arr[0],arr[1]);

              }

              bufr.close();

              System.out.println(prop);

       }

//     设置和获取元素。

       public static void setAndGet()

       {

              Properties prop = newProperties();

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

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

              //System.out.println(prop);

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

              //System.out.println(value);

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

              Set<String> names =prop.stringPropertyNames(); //1.6后才有的方法

              for(String s : names)

              {

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

              }

       }

}

 

7、IO流(Properties练习)

  • 用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。
  • 很容易想到的是:计数器。可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。可是随着该应用程序的退出,该计数器也在内存中消失了。下一次在启动该程序,又重新开始从0计数。这样不是我们想要的。程序即使结束,该计数器的值也存在。下次程序启动在会先加载该计数器的值并加1后在重新存储起来。所以要建立一个配置文件。用于记录该软件的使用次数。

该配置文件使用键值对的形式。这样便于阅读数据,并操作数据。

键值对数据是map集合。数据是以文件形式存储,使用io技术。那么map+io -->properties.

配置文件可以实现应用程序数据的共享。

  • import java.io.*;

importjava.util.*;

class  RunCount

{

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

       {

              Properties prop = newProperties();

              File file = newFile("count.ini");

       //操作文件的时候先养成一个习惯,先把文件,封装成一个对象,封装和没有封装不一样,封装完成后,可以对于文件做判断

              if(!file.exists())

                     file.createNewFile();

              FileInputStream fis = newFileInputStream(file);//count.ini第一次的时候没有会报异常,因此要封装成File对象

              prop.load(fis);

              int count = 0;

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

              if(value!=null)

              {

                     count =Integer.parseInt(value);

                     if(count>=5)

                     {

                            System.out.println("您好,使用次数已到,拿钱!");

                            return ;

                     }

              }

              count++;

              prop.setProperty("time",count+"");

              FileOutputStream fos = newFileOutputStream(file);

              prop.store(fos,"");

              fos.close();

              fis.close();

       }

}

  • 目前能使用的配置文件有两种:一、用properties(键值对) 二、XML

/*

name=zhangsan //关系复杂的话,它描述不了。描述起来的话,操作也费劲。

age=20

 

<persons> //加入十个人信息,用xml是最方便的。

       <person id="001">

              <name>zhagnsan</name>

              <age>30</age>

              <address>bj</address>

       </person>

       <person>

              <name

       </person>

</persons>

*/

  • Java本身就有取这些数据的对象:org.w3c.dom中的Document,Document 接口表示整个 HTML或 XML 文档,可以用这个对象拿到这里面的所有的数据。Java取这里面的数据特别的麻烦,要用好多对象和好多方法来完成,有一邦牛人们就做了一个更简单的工具叫做dom4j:dom forjava four

 

8、IO流(PrintWriter)

  • IO包中的其他类:打印流,PrintWriter与PrintStream可以直接操作输入流和文件。
  • PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。其中不仅有write()方法,其中最牛的是打印方法println()。它可以对于基本数据类型进行直接的操作。它可以保证数据的原样性将数据打印出去。可以传入对象,String。而write(intb)将一个int型的数传进去,它打印的是低8位。
  • 打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。
  • 字节打印流:

PrintStream(能直接操作文件,凡是和文件相关的流对象都是比较重要的流对象)

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

1,file对象。    PrintStream(Filefile)

2,字符串路径。 PrintStream(String fileName)

3,字节输出流。 PrintStream(OutputStream out)

  • 字符打印流:

PrintWriter(非常的常用,web开发的时候,都用这个对象把数据一条一条的打到客户端去,让客户浏览器对于它解释执行)

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

1,file对象。 PrintWriter(File file)

2,字符串路径。 PrintWriter(String fileName)

3,字节输出流。 PrintWriter(OutputStream out)

4,字符输出流。 PrintWriter(Writer out)

  • import java.io.*;

class  PrintStreamDemo

{

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

       {

              BufferedReader bufr =

                     new BufferedReader(newInputStreamReader(System.in));

   //autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区

              PrintWriter out = newPrintWriter(new FileWriter("a.txt"),true);//将文件封装到流里面就可以自动刷新了。

              String line = null;

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

              {

                     if("over".equals(line))

                            break;

                     out.println(line.toUpperCase());

                     //out.flush();

              }

              out.close();

              bufr.close();

       }    

}

 

9、IO流(合并流)

  • 序列流,SequenceInputStream对多个流进行合并。(Java.io中的类,它没有对应的OutputStream)
  • 构造方法:SequenceInputStream(InputStreams1, InputStream s2),接收两个流对象,将最后一个流的-1做为大流的-1结束了。将多个源对应一个目的,变成为一个源对应一个目的。这个源称做:sequenceInputStream.
  • import java.io.*;

importjava.util.*;

class SequenceDemo

{

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

       {

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

              v.add(newFileInputStream("c:\\1.txt"));

              v.add(newFileInputStream("c:\\2.txt"));

              v.add(newFileInputStream("c:\\3.txt"));

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

              SequenceInputStream sis = newSequenceInputStream(en);

              FileOutputStream fos = newFileOutputStream("c:\\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();

       }

}

 

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

 

0 0