zoukankan      html  css  js  c++  java
  • JAVA基础--IO输入输出(File使用)17

    一、 File中的方法

      1.  列举方法

     1 /*
     2  * 获取指定目录以及子目录下的所有文件和文件夹
     3  */
     4 public class ListFilesDemo {
     5     public static void main(String[] args) {
     6         
     7         File dir = new File("d:/test");
     8         getFiles(dir);
     9     }
    10     //获取指定目录下的文件或文件夹
    11     public static void getFiles(File dir) {
    12         
    13         //判断dir所表示的文件或文件夹是否存在
    14         if( !dir.exists() ){
    15             throw new RuntimeException("传递的文件或文件夹不存在");
    16         }
    17         //判断dir是否是目录
    18         if( !dir.isDirectory() ){
    19             throw new RuntimeException("传递的文件对象表示的不是一个有效的目录");
    20         }
    21         
    22         //获取指定目录 下的文件和文件夹
    23         File[] files = dir.listFiles();
    24         //判断当前指定的目录Java是否有权限访问,如果没有权限会得到null
    25         if( files != null ){
    26             //遍历文件数组
    27             for( File file : files ){
    28                 //取出数组中的某个File对象
    29                 if( file.isDirectory() ){
    30                     //判断 成立说明当前数组中保存的某个文件对象一定是目录(文件夹)
    31                     getFiles(file);
    32                 }else{
    33                     //判断不成立,说明当前从数组中取出的文件对象一定是文件
    34                     System.out.println("正在删除的文件是:"+file.getName()+",删除的结果是:"+file.delete());
    35                 }
    36                 //程序如果执行到这里,说明一定将某个目录中的文件删除完成,紧接着删除这个目录
    37                 System.out.println("被删除的文件夹是:"+file.getName()+",删除的结果是:"+file.delete());
    38             }
    39         }
    40     }
    41 }

      2. 递归技术

    上述的遍历多级目录,使用到的方法在调用自己。这个技术被称为方法的递归调用。

    递归:方法调用方法。

             直接递归:方法在自己的方法体中又调用自己。

             间接递归:A方法调用B方法,B方法调用C ...... 最后一个方法调用A方法。

     1     /*
     2  * 需求:计算1~5的和值,禁止使用循环。
     3  */
     4 public class DiGui {
     5     public static void main(String[] args) {
     6         int num = 5;
     7         int sum = getSum( num );
     8         System.out.println(sum);
     9     }
    10     
    11     public static int getSum(int num) {
    12         
    13         if( num > 1 ){
    14             return num + getSum( num -1 );
    15         }
    16         return 1;
    17     }
    18 }

             递归程序注意的细节:

                       1、递归调用一定要在程序添加判断,保证递归可以停止。否则就是无限递归调用。会导致栈内存溢出。

                       2、如果递归调用有判断,但是判断的语句还没有结束就可能导致栈溢出。因此递归的次数一定不要太多。

      3.  文件队列

     1 /*
     2  * 使用文件队列获取指定目录以及子目录下的文件和文件夹
     3  */
     4 public class ListFilesDemo2 {
     5     public static void main(String[] args) {
     6         File dir = new File("d:/test");
     7         getFiles(dir);
     8     }
     9     //获取指定目录以及子目录下的文件和文件夹
    10     public static void getFiles(File dir) {
    11         //定义集合容器
    12         LinkedList<File> list = new LinkedList<File>();
    13         //将传递进来的文件夹先保存到集合容器中
    14         list.addLast(dir);
    15         //遍历集合容器
    16         while( list.size() > 0 ){
    17             //只要循环成立,说明集合容器中就会有文件夹存在
    18             File file = list.removeFirst();
    19             //获取从容器中取出的这个文件夹下的所有文件和文件夹
    20             File[] files = file.listFiles();
    21             //判断当前的目录Java是否有权限.判断files是否为null
    22             if( files != null ){
    23                 for( File f : files ){
    24                     //遍历当前从容器中取出的这个文件夹下的每个文件或文件夹对象
    25                     if( f.isDirectory() ){
    26                         //判断成立,说明当前得到的子文件对象一定是文件夹,添加到集合中
    27                         list.addLast(f);
    28                     }else{
    29                         ///当前的f一定是文件
    30                         System.out.println(f);
    31                     }
    32                 }
    33             }
    34         }
    35     }
    36 }

     二、 文件过滤器

      1. 文件过滤器介绍

    我们在使用list或者listFiles方法列出某个目录下的文件或者文件夹的时候,是将所有的全部列出,有时我们并不需要某个目录下的所有文件或文件夹,而是希望列出符合条件的文件或文件夹。

    可以在使用list或listFiles方法时,给方法传递一个符合用户需求的过滤对象,这个对象可以帮助list和listFiles方法在列出目录下文件或文件夹的时候,根据传递的过滤对象将符合条件的文件和文件夹列出,不符合的就会被过滤掉。

    在Java中提供了2个负责过滤的过滤器:

             FilenameFilter:文件名过滤器:是通过文件或文件夹的名称过滤

             FileFilter文件过滤器:通过文件或文件夹对象过滤器

      2.  FilenameFilter接口

     

     1 /*
     2  * 自己定义文件名过滤器
     3  */
     4 public class MyFilenameFilter implements FilenameFilter{
     5     //定义成员变量,记录传递的过滤的名称
     6     private String suffix;
     7     //定义构造方法,让使用者在创建过滤器对象的时候指定需要过滤的条件
     8     public MyFilenameFilter(String suffix){
     9         this.suffix = suffix;
    10     }
    11     /*
    12      *  解释FilenameFilter中的accept方法上的两个参数
    13      *      File dir : 是当前需要列举的那个目录
    14      *      String name:是当前指定的目录下的文件或文件夹的名称
    15      */
    16     public boolean accept(File dir, String name) {
    17         //System.out.println(dir + "....." + name);
    18         return name.endsWith(this.suffix);
    19     }
    20     
    21 }
    22 
    23 /*
    24  * 演示FilenameFilter过滤器的使用
    25  */
    26 public class FilenameFilterDemo {
    27     public static void main(String[] args) {
    28         
    29         //创建文件对象
    30         File dir = new File("d:/test/day07_code");
    31         /*
    32          * 当我们在程序中使用list方法的时候,list方法会先列出当前目录下的所有文件和文件夹
    33          * 然后将这些文件和文件夹传递给指定的过滤器对象,
    34          * 如果过滤器中的accept方法返回的true,就认为当前这个文件或文件夹是需要保留的
    35          * 如果过滤器中的accept方法返回的false,就认为当前这个文件或文件夹是不需要的
    36          */
    37         String[] list = dir.list(new MyFilenameFilter(".java"));
    38         
    39         //遍历
    40         for (String s : list) {
    41             System.out.println(s);
    42         }
    43     }
    44 }

      3. FileFilter接口

     1 /*
     2  * 自定义FileFilter过滤器对象
     3  */
     4 public class MyFileFilter implements FileFilter{
     5     private String suffix;
     6     public MyFileFilter(String suffix){
     7         this.suffix = suffix;
     8     }
     9     /*
    10      * 解释FileFilter中的accept方法上接收的参数
    11      *     File pathname : 表示的当前目录下的那个文件或文件夹对象
    12      */
    13     public boolean accept(File pathname) {
    14         //System.out.println(pathname.isDirectory() +".."+pathname.getName()+"..."+pathname.isFile());
    15         //需要将扩展名为 .mp3的文件保留下来
    16         return pathname.isFile() && pathname.getName().endsWith(this.suffix);
    17     }
    18 
    19 }
    20 
    21 /*
    22  * 演示FileFilter的使用
    23  */
    24 public class FileFilterDemo {
    25     public static void main(String[] args) {
    26         
    27         //创建File对象
    28         File dir = new File("d:/test");
    29         
    30         /*
    31          * 获取指定目录下的文件或文件夹
    32          * 
    33          * 当我们调用File类中的listFiles方法,并传递以了一个FileFilter过滤器对象
    34          * listFiles方法也是先将指定目录下的所有文件和文件夹获取到,
    35          * 然后将这些文件或文件夹对象逐一传递给FileFilter中的accept方法。
    36          * 
    37          */
    38         File[] files = dir.listFiles(new MyFileFilter(".java"));
    39         
    40         for ( File file : files){
    41             System.out.println(file);
    42         }
    43     }
    44 }

       4. 过滤器练习

    需求:获取指定目录以及子目录下的文件(扩展名为.java).

     1 /*
     2  * 需求:获取指定目录以及子目录下的文件(扩展名为.java)
     3  * 
     4  */
     5 public class FilterTest {
     6     public static void main(String[] args) {
     7         
     8         File dir = new File("d:/test");
     9         getFiles(dir);
    10     }
    11 
    12     public static void getFiles(File dir) {
    13         
    14         //列出指定目录下的文件和文件夹
    15         File[] files = dir.listFiles( new FileFilter(){
    16 
    17             /*
    18              * 书写过滤的条件:
    19              *     如果是只过滤当前的目录,那么在书写过滤器条件的时候,
    20              *     只需要判断是否是文件和文件的扩展名。
    21              * 
    22              *  如果需要多级目录文件获取,这时在书写过滤器的时候,
    23              *  判断的条件中需要保留文件夹,和文件(扩展名必须是符合条件)
    24              */
    25             public boolean accept(File pathname) {
    26                 return (pathname.isDirectory())  || 
    27                         (pathname.isFile() && pathname.getName().endsWith(".txt"));
    28             }
    29             
    30         } );
    31         //判断
    32         if( files != null ){
    33             //遍历
    34             for (File file : files) {
    35                 if( file.isDirectory() ){
    36                     getFiles(file);
    37                 }else{
    38                     System.out.println(file);
    39                 }
    40             }
    41         }
    42     }
    43 }

     三、   IO流技术

      1. 流的分类

    File类:它主要是操作文件和文件夹,并不能读写文件中的数据。

    我们如果需要操作保存在文件中的数据,这时只能使用Java中提供的IO流对象。

       

    IO:Input   Output。

    IO流:它是使用Java中提供的众多的对象,和文件中的数据进行交互。

    IO流如果按照操作数据的方向:

             输入流:Input,读取数据。

             输出流:Output,写出数据。

    IO流如果按照操作的数据类型:

             字节流:它全部是以字节形式操作(读写)的数据

             字符流:全部是以字符的形式操作(读写)数据

    上课以数据类型分类:现讲字节流,再讲字符流。

             字节流和字符流它们对文件中的数据操作规律是一致的。主要会一种,其他的都可以照着模版代码进行抄写。

      2. 字节流介绍

    任何数据在电子设备中存储的方式都是二进制形式(字节)。我们就可以直接以字节方式读取文件中的数据,或者以字节的方式给文件中写数据。

    字节流:

             字节输入流:它是负责以字节的方式从文件中读取数据。在程序中我们会获取到读取的字节数据。

             字节输出流:它是负责以字节的方式将程序(内存)中的数据写到文件中。

      3.  字节输出流

    OutputStream:它是所有字节输出流的超类(基类、根类)。它中肯定定义了应该如何将字节写到底层文件中的最基本(共性)的方法。

    使用Java程序操作Java以外的其他数据(数据库,硬盘,网络,其他语言开发的程序),首先需要让我们的Java程序和其他的资源平台获取连接(关联),在这个连接中进行数据的交互。交互结束之后一定要记住将彼此之间的连接断开。因此我们使用Java中的IO流技术操作其他设备上的数据,这时操作完一定要记得调用close方法。

    write(byte[] b) 将指定的字节数组中的全部数据写到底层指定的设备中。

    write(byte[] b , int off , int len) 将指定的字节数组中的数据从off位置开始,共计写出len个。

    write(int b) 将int类型数据中的最低位一个字节写出。

      4.  文件字节输出流

    FileOutputStream:它是专门负责将字节数据写到文件中。

            

     1 /*
     2  * 演示字节输出流
     3  *   使用输出流,往出写数据的时候,如果指定的文件不存在,
     4  *   这时输出流会自动的在指定的目录下创建这个文件,并将数据写到文件中。
     5  *   
     6  *   使用输出流的时候,文件不存在会创建,如果文件存在,会覆盖。原来文件中的数据全部丢失。
     7  */
     8 public class FileOutputStreamDemo {
     9     public static void main(String[] args)throws IOException {
    10         method3();
    11     }
    12     // write(byte b)
    13     public static void method3() throws IOException {
    14         //创建负责写字节数据的流对象
    15         FileOutputStream fos = new FileOutputStream("d:/aa.txt");
    16         /*
    17          * OutputSteam它写出的是字节数据,字节数据的范围是-128到127之间。
    18          *  其中提供的write(int b) 它本质只能写一个字节,但是接收的int类型的数据
    19          *   int类型的数据在内存中共计占用4个字节,write方法它其实只能将4个字节中
    20          *   最低一位上的那个字节数据写到文件中。
    21          *   
    22          *   97 : 0000 0000 0000 0000 0000 0000 0110 0001
    23          *   353:0000 0000 0000 0000 0000 0001 0110 0001
    24          *       
    25          */
    26         fos.write(97);
    27         fos.write(353);
    28         
    29         fos.close();
    30     }
    31     //write(byte[] b , int off , int len)
    32     public static void method2() throws IOException {
    33         
    34         //创建负责写字节数据的流对象
    35         FileOutputStream fos = new FileOutputStream("d:/aa.txt");
    36         
    37         //创建字节数组
    38         byte[] b = {65,66,67,68,69};
    39         //调用写的方法写数据
    40         fos.write(b , 1 , 2);
    41         
    42         //关闭流对象
    43         fos.close();
    44         
    45     }
    46     //演示 write(byte[] b);
    47     public static void method() throws IOException {
    48         
    49         //创建负责写字节数据的流对象
    50         FileOutputStream fos = new FileOutputStream("d:/aa.txt");
    51         
    52         //创建字节数组
    53         byte[] b = {65,66,67,68,69};
    54         //调用写的方法写数据
    55         fos.write(b);
    56         
    57         //关闭流对象
    58         fos.close();
    59     }
    60 }

      5.  追加数据和换行

     1 /*
     2      * 文件写字符串数据,并换行
     3      */
     4     public static void method5() throws IOException {
     5 
     6         FileOutputStream fos = new FileOutputStream("d:/aa.txt",true);
     7         
     8         //获取操作系统支持的换行符
     9         String line_separator = System.getProperty("line.separator");// 
    
    10         String s = "Java基础正在学习IO技术"+line_separator;
    11         
    12         fos.write(s.getBytes());
    13         
    14         fos.close();
    15     }
    16     /*
    17      * 在文件的末尾追加数据
    18      * FileOutputStream(String name, boolean append)
    19      *     如果创建FileOutputStream的时候,在构造方法中指定的boolean值为true
    20      *     这时需要关联的文件如果不存在,它会创建,
    21      *     如果已经存在,并且其中有数据,会在原来文件的末尾继续追加数据
    22      */
    23     public static void method4() throws IOException {
    24         
    25         FileOutputStream fos = new FileOutputStream("d:/aa.txt",true);
    26         
    27         fos.write(101);
    28         fos.write(102);
    29         fos.write(103);
    30         fos.write(104);
    31         
    32         //关流
    33         fos.close();
    34     }

      6.  输出流练习

     1 /*
     2  * 需求:将指定目录和子目录下的指定扩展名(.java)的文件所在路径写到一个文件中,形成一个文件清单。
     3  * 分析:
     4  *         获取符合条件的文件,然后将其路径得到。再使用输出流写到文件中即可
     5  */
     6 public class FileOutputStreamTest {
     7     public static void main(String[] args) throws IOException {
     8         
     9         File dir = new File("d:/test");
    10         FileOutputStream fos = new FileOutputStream("d:/文件清单.txt");
    11         getListFile(dir,fos);
    12         fos.close();
    13     }
    14     //获取指定目录下的文件清单
    15     public static void getListFile(File dir ,FileOutputStream fos) throws IOException {
    16         
    17         File[] files = dir.listFiles( new FileFilter(){
    18             public boolean accept(File pathname) {
    19                 return (pathname.isDirectory()) || 
    20                         (pathname.isFile() && pathname.getName().endsWith(".avi"));
    21             }
    22         } );
    23         //判断
    24         if( files != null ){
    25             for (File file : files) {
    26                 if( file.isDirectory() ){
    27                     getListFile(file,fos);
    28                 }else{
    29                     //一定是文件
    30                     System.out.println(file);
    31                     String path = file.getAbsolutePath() + System.getProperty("line.separator");
    32                     fos.write(path.getBytes());
    33                 }
    34             }
    35         }
    36     }
    37 }

      7.  字节输入流

    InputStream:它是字节输入流的超类(基类、根类),它中定义的是字节输入流如何读取字节数据的方法。

    所有输入流:它们都有read方法,负责从底层读取数据的。如果读取到文件末尾统一返回的都是-1。

    int read() 这个方法调用一次,就会从底层文件中获取一个字节数据,并返回这个字节数据。

    int read(byte[] b) 调用一次,会从底层文件中读取若干个字节数据,并将这些字节数据存储在byte数组中,每次都是从数组的零位置开始往后存储。返回的int值表示的是给byte数组中真正存储的字节个数。

    int read(byte[]b , int off , int len) 调用一次,从底层读取若干字节数据,将数据存储在b数组中,但是是从off位置开始存储,共计只能存储len个。返回的int值表示是的是给数组中存储的字节个数。

       8.   文件字节输入流

    FileInputStream:它是专门负责从文件中读取字节数据。

     1 /*
     2  * 演示字节输入流
     3  */
     4 public class FileInputStreamDemo {
     5 
     6     public static void main(String[] args) throws IOException {
     7         method3();
     8     }
     9     //一次读取多个字节数据
    10     public static void method3() throws IOException {
    11         //创建输入流对象和需要被读取的文件进行关联
    12         FileInputStream fis = new FileInputStream("d:/aa.txt");
    13         /*
    14          * 定义数组充当临时的容器,存储每次从文件中读取到的若干个字节数据。
    15          * 一般定义的数组如果是存储读取到的数据,这个数组一般会是1024的整数倍
    16          */
    17         byte[] buf = new byte[1024];
    18         //定义变量,记录每次给数组中存储的字节个数
    19         int len = 0;
    20         //使用循环读取数据
    21         while( ( len = fis.read( buf ) ) != -1 ){
    22             /*
    23             for( int i = 0 ; i < len ; i++ ){
    24                 System.out.print(buf[i]+" ");
    25             }
    26             */
    27             System.out.println(new String( buf , 0 , len ));
    28         }
    29         
    30         //关流
    31         fis.close();
    32     }
    33     //使用循环读取文件中的数据 ,一次读取一个
    34     public static void method2() throws IOException {
    35         
    36         //创建输入流对象和需要被读取的文件进行关联
    37         FileInputStream fis = new FileInputStream("d:/aa.txt");
    38         //定义变量记录每次读取到的字节数据
    39         int ch = 0;
    40         //使用while循环读取数据
    41         while( ( ch = fis.read( ) ) != -1 ){
    42             System.out.println(ch);
    43         }
    44         //关流
    45         fis.close();
    46     }
    47     //演示 read()
    48     public static void method() throws IOException {
    49         
    50         //创建输入流对象和需要被读取的文件进行关联
    51         FileInputStream fis = new FileInputStream("d:/aa.txt");
    52         
    53         //读取字节数据
    54         System.out.println(fis.read());
    55         System.out.println(fis.read());
    56         System.out.println(fis.read());
    57         System.out.println(fis.read());
    58         
    59         //关流
    60         fis.close();
    61     }
    62 }

     9.  复制文件练习

     1 /*
     2  * 需求:复制指定的文件到指定的目录下
     3  * 
     4  */
     5 public class CopyFileTests {
     6     public static void main(String[] args) throws IOException{
     7         copyFile2();
     8     }
     9     //使用数组复制
    10     public static void copyFile2() throws IOException{
    11 
    12         //定义输入流读取文件
    13         FileInputStream fis = new FileInputStream("d:/1.avi");
    14         //定义输出流写文件
    15         FileOutputStream fos = new FileOutputStream("c:/1.avi");
    16         
    17         //在开始复制文件之前获取系统的时间
    18         long start = System.currentTimeMillis();
    19         
    20         //保存每次读取的字节个数
    21         int len = 0;
    22         /*
    23          * 定义字节数组保存数据
    24          * 8二进制 = 1字节
    25          * 8bit = 1Byte
    26          * 1024B = 1KB
    27          * 1024KB = 1MB
    28          * 1024MB = 1GB
    29          * 1024GB = 1TB
    30          * 1024TB = 1PB
    31          */
    32         byte[] buf = new byte[8192];
    33         //使用循环读取数据
    34         while( ( len = fis.read( buf ) ) != -1 ){
    35             //使用输出流写到文件中
    36             fos.write( buf, 0 , len );
    37         }
    38         
    39         //循环结束,数据已经复制完成
    40         long end = System.currentTimeMillis();
    41         System.out.println("复制文件所用时间:"+(end - start));
    42         
    43         //关流
    44         fis.close();
    45         fos.close();        
    46     }
    47     //演示 一次读取一个字节的方式复制
    48     public static void copyFile() throws IOException{
    49         
    50         //定义输入流读取文件
    51         FileInputStream fis = new FileInputStream("d:/1.mp3");
    52         //定义输出流写文件
    53         FileOutputStream fos = new FileOutputStream("c:/1.mp3");
    54         
    55         //在开始复制文件之前获取系统的时间
    56         long start = System.currentTimeMillis();
    57         
    58         //保存每次读取的字节数据
    59         int ch = 0;
    60         //使用循环读取数据
    61         while( ( ch = fis.read() ) != -1 ){
    62             //使用输出流写到文件中
    63             fos.write(ch);
    64         }
    65         
    66         //循环结束,数据已经复制完成
    67         long end = System.currentTimeMillis();
    68         System.out.println("复制文件所用时间:"+(end - start));
    69         
    70         //关流
    71         fis.close();
    72         fos.close();
    73     }
    74 }
  • 相关阅读:
    采用闭锁(CountDownLatch)控制线程的先后顺序(一)
    采用java信号量(semaphore)让线程轮流打印
    生产者消费者模式的java实现(实现四)
    生产者消费者模式的java实现(实现三)
    生产者消费者模式的java实现(实现二)
    生产者消费者模式的java实现(实现一)
    求最大子串和 最长子串的java写法
    Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process 异常处理
    定时任务服务器不定时重启原因解析
    centos 6.3 + gerrit-2.8.6 + repo 实践
  • 原文地址:https://www.cnblogs.com/Kubility123/p/7716736.html
Copyright © 2011-2022 走看看