黑马程序员——Java基础---IO(三)--File类、Properties类、打印流、序列流(合并流)

时间:2021-05-02 19:40:04

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

                   File类

一、概述

1、File类:文件和目录路径名的抽象表现形式

2、特点:

        1)用来将文件或文件夹封装成对象

        2)方便于对文件与文件夹的属性信息进行操作,因此是对流操作的一种补充

        3)File类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变

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

 

二、File对象创建

方式一:      

             File f =new File("a.txt");

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

 方式二:

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

        将文件所在目录路径和文件一起传入,指定文件路径。

 方式三:

            File d=new File("c:\\abc");

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

        将文件目录路径封装成对象。再创建文件对象。降低了文件于父目录的关联性。

小知识:

        File.separator表示目录分隔符,可以跨平台使用。相当于路径中的“\”(双斜杠\\在windows中表示表示转义后的分隔符,但是在linux系统中就不是)。

三、File类的常见方法

  1 import java.io.*;
  2 /*
  3 
  4 File 类常见方法
  5 1    创建    
  6         boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回 false.
  7                                     和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
  8         boolean mkdir():创建文件夹。
  9         boolean mkdirs(): 创建多级文件夹。
 10 
 11 2    删除
 12         boolean delete():删除失败返回false。如果文件正在被使用,则删除不了 返回 false 、
 13         void deleteOnExit()  :  在程序退出时删除  指定文件。
 14 
 15 3    判断。
 16         boolean exists():文件是否存在
 17         isFile();  检查文件名是否为正常文件
 18         isDirectory():  是否是路径(目录)
 19         f.canExecute()    判断文件是否 可执行
 20         isHidden();        是否为隐藏文件
 21         isAbsolute():    是否有  绝对路径(目录)
 22 
 23 4    获取信息
 24         getName();//获取文件名
 25 
 26         getpath(): //获取文件的相对路径(即创建的对象传入的参数是什么就获取到什么)
 27 
 28         getParent();   //获取文件父目录。返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
 29                       //如果相对路径中有上一层目录,那么该目录就是返回结果。
 30 
 31         getAbsolutePath://获取文件的绝对路径  
 32 
 33         long lastModified()        //返回的是    最后一次修改时间
 34 
 35         long length//返回文件长度
 36 */
 37 class FileDemo
 38 {
 39     public static void main(String[] args)throws IOException
 40     {
 41         consMethod();
 42     }
 43     public static void method_5()
 44     {
 45         File f1=new File("file.txt");
 46 
 47         File f2=new File("c:\\haha.java");
 48 
 49         sop("rename:"+f1.renameTo(f2));
 50     }
 51     public static void method_4()
 52     {
 53         File f=new File("file4.txt");
 54         sop("path:"+f.getPath());//获取相对路径
 55         sop("abspath"+f.getAbsolutePath());//获取绝对路径
 56         sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null
 57                                     //如果相对路径中有上一层目录那么该目录就是返回结果
 58     }
 59     public static void method_3()throws IOException
 60     {
 61         File f =new File("d:\\javalianxi\\day20\\file2.txt");
 62         f.createNewFile();//创建文件
 63         f.mkdir();//创建一级目录
 64         //记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
 65         //通过exists判断
 66         sop("dir:"+f.isDirectory());//返回是否是 文件夹
 67         sop("file:"+f.isFile());  //返回是否是文件
 68         sop("执行:"+f.canExecute());//返回是否可执行
 69         sop(f.isAbsolute());//返回是否是绝对路径
 70     }
 71     public static void method_2()
 72     {
 73         File f=new File("file.txt");
 74         sop("exists:"+f.exists());
 75         sop("execute:"+f.canExecute());
 76         //创建文件夹
 77         File dir=new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");
 78         sop("mkdir:"+dir.mkdirs());//创建多级目录
 79     }
 80     public static void method_1()throws IOException
 81     {
 82         File f=new File("file.txt");
 83         
 84         //sop("create:"+f.createNewFile());
 85         //sop("delete:"+f.delete());
 86     }
 87 
 88     public static void sop(Object obj)
 89     {
 90         System.out.println(obj);
 91     }
 92     //创建File对象
 93     public static void consMethod()throws IOException
 94     {
 95         //将a.txt封装成file对象。可以将已有的和未出现的文件夹封装成对象。
 96         File f1=new File("a.txt");
 97         File f2=new File("c:\\abc","b.txt");
 98         File d=new File("c:\\abc");
 99         File f3=new File(d,"c.txt");
100         new File("c:\\abc").mkdir();
101         f2.createNewFile();//创建新文件
102         
103         sop("f1:"+f1);
104         sop("f2:"+f2);
105         
106         File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator/*为跨平台目录符号*/+"a.txt");
107         sop("f3:"+f4);
108     }
109 }

5、列出文件及文件过滤

        static File[] listRoots();//列出可用的文件系统根目录,即系统盘符

        String[] list();

        //列出当前目录下所有文件,包括隐藏。调用list方法的file对象必须是封装了一个目录。该目录还必须存在。

        String[]list(FilenameFilter filter);

        //返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。

        //FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,accept(Filedir,String name),返回的是boolean型,对不符合条件的文件过滤掉。

        File[] listFiles();//返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹

        File[] ListFiles(FilenameFilterfilter);//返回抽象路径名数组,获取目录中满足指定过滤器的文件或目录。

 1 import java.io.*;
 2 class FileDemo2
 3 {
 4     public static void main(String[] args)
 5     {
 6     listRootsDemo();
 7     }
 8     public static void listDemo_1()//建立文件dir关联C盘  之后将C盘文件遍历获取名字和长度
 9     {
10         File dir=new File("c:\\");
11         File[] files=dir.listFiles();//返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹
12         for(File f:  files)
13         {
14             System.out.println(f.getName()+"::"+f.length());
15         }
16     }
17     public static void listDemo_2()//获取一个目录下所有的.java文件方法  
18     {
19         File dir = new File("d:\\javalianxi\\day19");
20         String[] arr=dir.list(new FilenameFilter()//建立匿名内部类,取出末尾为。java的文件
21         {
22             public boolean accept(File dir,String name)      
23             {
24                 //System.out.println("dir:"+dir+".....name::"+name);
25                 /*
26                 if(name.endsWith(".java"))
27                 return true;
28                 else
29                 return false;*/
30                 return  name.endsWith(".java");//判断文件名是否是以.java结尾
31                 
32             }
33 
34         });
35         System.out.println("len:"+arr.length);
36         for(String name:arr)  //遍历数组 
37         {
38             System.out.println(name);
39         }
40     }
41     public static void listDemo()
42     {
43         File f=new File("c:\\abc.txt");
44         String[]names =f.list();//调用list方法的file对象必须是封装了一个目录。该目录还必须存在
45         for(String name : names)
46         {
47             System.out.println(name);
48         }
49     }
50     public static void listRootsDemo()
51     {
52         File[]files =File.listRoots();//列出可用的文件系统根目录,即系统盘符
53         for(File f:files)
54         {
55             System.out.println(f);
56         }
57     }
58 }

四、递归

 1 import java.io.*;
 2 /*
 3 列出指定目录下文件或者文件夹,包括子目录中的内容
 4 也就是列出指定目录下所有内容。
 5 
 6 因为目录中还有目录,只要使用同一个列出目录功能的函数完成既可。、
 7 在列出过程中出现的还是目录的话,还可以再次调用本功能,
 8 也就是函数自身调用自身。
 9 这种表现形式,或者编程手法,称为递归
10 
11 递归要注意:
12 1    限定条件
13 2    要注意递归的次数,尽量避免内存溢出。因为每次调用自身的时候都会先执行下一次调用自己的方法,
14     所以会不断在栈内存中开辟新空间,次数过多,会导致内存溢出。
15 
16 
17 */
18 class FileDemo3
19 {
20     public static void main(String[] args)
21     {
22         File dir=new File("d:\\javalianxi\\day18");//关联指定路径
23         list(dir,0);
24     }
25     public static String getLevel(int level)//获取目录为几级目录,目录名前添加"   ",显示出层次感
26     {
27         StringBuilder sb=new StringBuilder();//建立字符串缓冲区,用来存储空格
28         while(level>0){
29         sb.append("   ");
30         level--;}
31         return sb.toString();//返回大量空格
32     }
33     public static void list(File dir,int level)
34     {
35         level++;//定义目录等级,多调用一次,目录等级加1
36         File files[]=dir.listFiles();////获取本目录下的所以文件和目录的抽象路径
37         for(int x=0;x<files.length;x++)
38         {
39             if(files[x].isDirectory())//判断是否是目录
40                 list(files[x],level);//是目录,则继续遍历文件
41             else
42                 System.out.println(getLevel(level)+files[x]);//打印出文件名
43         }
44     }
45 }
 1 /*
 2 删除一个带内容的目录
 3 删除原理
 4 在windows中,删除目录从里面往外删除的
 5 
 6 既然是从里往外删除。就需要用到递归
 7 */
 8 import java.io.*;
 9 class RemoveDir
10 {
11     public static void main(String[] args)
12     {
13         File dir=new File("D:\\javalianxi\\day20\\abc - 副本");//关联目录
14         removedir(dir);//将目录传入
15     }
16     public static void removedir(File dir)//删除目录方法
17     {
18         File[] files=dir.listFiles();//列出目录下的所以文件和文件夹
19         for(int x=0;x<files.length;x++)
20         {
21             if(files[x].isDirectory())//如果文件是目录
22                 removedir(files[x]);//继续调用本方法
23             else
24                 System.out.println(files[x].toString()+":-file-:"+files[x].delete());//打印文件名,并删除文件,删除成功返回true
25         }
26         System.out.println(dir+"::dir::"+dir.delete());//删除目录
27     }
28 }

3.将一个指定目录下的java文件的绝对路径,存储到一个文本文件中

 1 /*
 2 练习
 3 将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
 4 建立一个java文件列表文件。
 5 
 6 思路:
 7 1,对指定的目录进行递归。
 8 2,获取递归过程所以的java文件的路径。
 9 3,将这些路径存储到集合中。
10 4,将集合中的数据写入到一个文件中。
11 
12 */
13 import java.io.*;
14 import java.util.*;
15 class  JavaFileList
16 {
17     public static void main(String[] args) throws IOException
18     {
19         File dir=new File("d:\\javalianxi\\day19");//关联指定目录
20         List <File>list=new ArrayList<File>();//定义一个List集合,用于存储.java文件的File对象 
21         fileToList(dir,list);//调用获取文件路径方法 
22         File file=new File(dir,"javapath.txt");//指定写入文件
23         writeToFile(list,file.toString()); //调用写入文件方法,将集合和文件名传入
24         
25     }
26     public static void fileToList(File dir,List<File> list)//获取指定文件夹内的所有java文件的绝对路径,并存入集合中  
27     {
28         File files[]=dir.listFiles();//列出dir路径下的所以文件和目录
29         for(File file:files)  //遍历 
30         {
31             if(file.isDirectory())//如果是目录,则继续调用本函数
32                 fileToList(file,list);
33             else
34             {
35                 if(file.getName().endsWith(".java"))//判断是否是java文件
36                     list.add(file);//是,将文件存入集合中
37             }
38         }
39         
40     }
41 
42     public static void writeToFile(List<File> list,String javaListFile)throws IOException
43     {
44         BufferedWriter bufw=null;//建立字符流缓冲区
45         try
46         {
47             bufw=new BufferedWriter(new FileWriter(javaListFile));//使用字符流缓冲区对象关联写入的文件 
48             for(File f:list)
49             {
50                 String path=f.getAbsolutePath();//获取绝对路径
51                 bufw.write(path);//写入
52                 bufw.newLine();//换行
53                 bufw.flush();//刷新
54             }
55         }
56         catch (IOException e)
57         {
58             throw e;
59         }
60         finally
61         {
62             try
63             {
64                 if(bufw!=null)
65                     bufw.close();
66             }
67             catch (IOException e)
68             {
69                 throw e;
70             }
71         }
72     }
73 }

Properties类

一、概述

1、Properties是Hashtable的子类,它具备Map集合的特点。而且它里面还有存储的键值对,都是字符串,无泛型定义。是集合中和IO技术相结合的集合容器。

2、特点:

        1)可用于键值对形式的配置文件

        2)在加载时,需要数据有固定的格式,常用的是:键=值

 

二、特有方法

1、设置

        Object setProperty(String key,String value);

        //设置键和值,调用Hashtable的方法put

2、获取

        String getProperty(String key);

        //指定key搜索value

        Set<String> stringPropertyName();

        //返回属性列表的键集,存入Set集合

3、加载流和存入流

        void load(InputStream ism);

        //从输入字节流中读取属性列表(键和元素对)。又称将流中的数据加载进集合。

        void load(Readerreader);

        //从输入字符流中读取属性列表(键和元素对)。又称将流中的数据加载进集合。

        voidlist(PrintStream out);//将属性列表输出到指定的输出流

        void store(OutputStreamout,String comments);

        //对应load(InputStream )将属性列表(键值对)写入输出流。comments属性列表的描述。

        void store(Writerwriter, String comments);

        //对应load(Reader)将属性列表(键值对)写入输出流。comments属性列表的描述。

示例:

 1 import java.io.*;
 2 import java.util.*;
 3 class lianxi2
 4 {
 5     public static void main(String[] args)throws IOException
 6     {
 7         //setAndGet();
 8         //method_1();
 9         loadDemo();
10     }
11     public static void method_1()throws IOException
12     {//演示,如何将流中的数据存储到集合中。
13     //想要将info.txt中键值数据存到集合中进行操作。
14     /*
15         1,用一个流和info.txt文件关联。
16         2,读取一行数据,将该行数据用"="进行切割。
17         3,等号左边作为键,右边作为值。存入到Properties集合中即可。
18 
19     */
20         BufferedReader bufr=new BufferedReader(new FileReader("info.txt"));//文件字符流读取方式关联文本文件,将其放入字符流缓冲区
21         String line=null;//设置字符串
22         Properties prop=new Properties();//设置集合。存储键值对
23 
24         while((line=bufr.readLine())!=null)//将缓冲区中文件存入字符串中,字符串不为空时
25         {
26             String[] arr=line.split("=");//以'='切割字符串
27             prop.setProperty(arr[0],arr[1]);//将键和值存入集合
28         }
29         bufr.close();//关闭流
30         System.out.println(prop);
31     }
32     public static void setAndGet()
33     {//    设置和获取元素。
34         Properties prop=new Properties();//新建存储键值对的集合
35         prop.setProperty("zhangsan","39");//存入新的   键和值
36         prop.setProperty("lisi","54");
37         System.out.println(prop);
38         
39 
40         //String value=prop.getProperty("lisi"); //通过键,获取键对应的值
41         //System.out.println(value);
42         prop.setProperty("lisi","44");
43         //System.out.println(prop);
44         Set<String> names = prop.stringPropertyNames();//获取prop中所有 键  的集合
45         for(String s:names)//遍历集合
46         {
47             System.out.println(s+":"+prop.getProperty(s));//打印所有键的名称和  打印 用键名获取到对应的值
48         }
49 
50     }
51     public static void loadDemo()throws IOException
52     {
53         Properties prop = new Properties();//新建用于存储键值对的集合
54         FileInputStream fis = new FileInputStream("info.txt");//将文件与文件读取流关联
55 
56         
57         prop.load(fis);//将流中的数据加载进集合。
58 
59         prop.setProperty("wangwu","39");//添加新的键值对
60 
61         FileOutputStream fos = new FileOutputStream("info.txt");//用文件输出流关联文件
62 
63         prop.store(fos,"haha");//属性列表(键值对)写入输出流,haha 为属性列表的描述
64 
65     //    System.out.println(prop);
66         prop.list(System.out); //将信息输出到文件
67 
68         fos.close();//关流
69         fis.close();
70     }
71 }

 

练习:

 1 /*
 2 用于记录应用程序运行次数。那么给出注册提示。
 3 
 4 很容易想到的是计数器
 5 可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。
 6 可是随着该应用程序的退出,该计数器也在内存中消失了
 7 
 8 下一次在启动该程序,又重新开始从0计数。
 9 这样不是我们需要的
10 
11 程序即使结束,该计数器的值也存在。
12 下次程序启动在会先加载该计数器的值并加1后在重新存储起来
13 
14 所以要建立一个配置文件。用于记录该软件的使用次数
15 
16 该配置文件使用键值对的形式。
17 这样便于阅读数据,并操作数据。
18 
19 键值对数据是map集合。
20 数据是以文件形式存储,使用io技术。
21 那么map+io--->properties
22 
23 配置文件可以实现应用程序数据的共享。*/
24 import java.io.*;
25 import java.util.*;
26 class RunCount
27 {
28     public static void main(String[] args)throws IOException
29     {
30         Properties prop=new Properties();//新建集合,用于存储键值对形式的数据
31         File file=new File("count.ini");//关联文件名为"count.ini"的文件
32         if(!file.exists())//如果文件不存在,创建文件
33             file.createNewFile();
34         FileInputStream fis=new FileInputStream(file);//文件输入流关联file文件
35         prop.load(fis);//将流中的数据加载进集合
36         int count=0;//定义计数器
37         String value=prop.getProperty("time");//将time作为键  value作为值,通过time键获取对应的值
38         if(value!=null)
39         {
40             count=Integer.parseInt(value);//将值 转换成int类型
41             if(count>=5)
42             {
43                 System.out.println("您好,使用次数已到,拿钱!");
44                 return ;
45             }
46         }
47         count++;
48         prop.setProperty("time",count+""); //将键和值存入集合中,存在增加或者覆盖
49         FileOutputStream fos=new FileOutputStream(file);//将文件输出流与文件相关联
50         prop.store(fos,"");//将缓冲区中的数据存入硬盘文件中
51         fos.close();//关闭流
52         fis.close();
53     }
54 }

   打印流

 1 /*
 2 
 3 打印流:
 4 该流提供了打印方法,可以将各种数据类型的数据都原样打印。
 5 
 6 字节打印流:
 7 PrintStream
 8 
 9 构造函数 可以接受的参数类型
10 1    file对象。File
11 2    字符串对象、String
12 3    字节输出流。OutputStream
13 
14 
15 
16 字符打印流
17 printWriter
18 构造函数可以接受的参数类型:
19 1    file对象。File
20 2    字符串对象:String
21 3    字节输出流;OutputStream
22 4    字符输出流:Writer
23 */
24 import java.io.*;
25 class PrintStreamDemo
26 {
27     public static void main(String[] args)throws IOException
28     {
29         BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//键盘录入的标准写法
30         PrintWriter out=new PrintWriter(new FileWriter("a.txt"),true);//文件写入流关联文件,创建打印流,将其放入
31         String line=null;                                            //当该文件不存在时,创建。存在时,续写,而不会覆盖
32         while((line=bufr.readLine())!=null)
33         {
34             if("over".equals(line))//定义结束字符
35                 break;
36             out.println(line.toUpperCase());
37         }
38     
39         out.close();//关流
40         bufr.close();
41 
42     }    
43 }

序列流

一、概述

1、SequenceInputStream对多个流进行合并。也被称为合并流。

2、常用构造函数

        SequenceInputStream(Enumeration<?extends FileInputStream> e)

二、常见合并多个流文件步骤

        1、创建集合,并将流对象添加进集合

        2、创建Enumeration对象,将集合元素加入。

        3、创建SequenceInputStream对象,合并流对象

        4、创建写入流对象,FileOutputStream关联写入文件

        5、利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作。

示例:

 1 import java.io.*;
 2 import java.util.*;
 3 class SequenceDemo
 4 {
 5     public static void main(String[] args)throws IOException
 6     {
 7         Vector<FileInputStream> v = new Vector<FileInputStream>();//创建容器  类型限定为 文件读取流
 8 
 9         v.add(new FileInputStream("c:\\1.txt"));//文件读取流关联文本文件,添加进 Vector容器中
10         v.add(new FileInputStream("c:\\2.txt"));
11         v.add(new FileInputStream("c:\\3.txt"));
12 
13         Enumeration<FileInputStream> en=v.elements();//创建枚举对象 
14         SequenceInputStream sis=new SequenceInputStream(en);//合并流  
15         FileOutputStream fos=new FileOutputStream("c:\\4.txt");//关联写入文件 
16         
17         
18         byte[] buf = new byte[1024];//定义字节容器,实现一次读一行的目的
19 
20         int len =0;//读写操作
21         while((len=sis.read(buf))!=-1)
22         {
23             fos.write(buf,0,len);
24         }
25 
26         fos.close();//关闭流资源
27         sis.close();
28 
29 
30     }
31 }

示例2:

 1 /* 
 2 切割文件 
 3 需求:将一个mp3文件按1M大小切割成几部分 
 4 思路:1、使用文件字节流关联mp3文件 
 5       2、定义一个容器存储1M大小的数据,当存储满时,写入一个新文件中 
 6  
 7 */  
 8 import java.util.*;
 9 import java.io.*;
10 class SplitFile
11 {
12     public static void main(String[] args)throws IOException
13     {
14         add();
15     }
16     public static void add()throws IOException//文件合流
17     {
18         /*ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();
19         for(int x=0;x<5;x++)
20         {
21             al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
22         }
23         //因为Enumeration是Vector特有的迭代方法,所以这里创建一个Enumeration类型的匿名内部类 
24         final Iterator <FileInputStream>it=al.Iterator();
25         Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
26         {
27             public boolean hasMoreElements()
28             {
29                 return it.hasNext();
30             }
31             public FileInputStream nextElement()
32             {
33                 return it.next();
34             }
35         };
36         */
37         
38         Vector<FileInputStream>  v=new Vector<FileInputStream> ();//创建Vector容器,元素限定为 文件输入流
39         for(int x=0;x<5;x++)//文件输入流  关联文件,并添加至Vector容器中
40         {
41             v.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
42         }
43 
44         
45         Enumeration <FileInputStream> en=v.elements();//创建枚举对象
46         SequenceInputStream sis=new SequenceInputStream(en);//合并流
47         FileOutputStream fos=new FileOutputStream("c:\\splitfiles\\0.mp3");//关联写入文件
48         byte buf[]=new byte[1024*1024];//定义第三方缓冲区容器
49         int len=0;
50         while((len=sis.read(buf))!=-1)//反复读写操作
51         {
52             fos.write(buf,0,len);    
53         }
54         fos.close();
55         sis.close();
56     }
57     public static void splitFile()throws IOException//文件切割
58     {
59         FileInputStream fis=new FileInputStream("c:\\1.mp3");
60         FileOutputStream fos=null;
61 
62         byte buf[]=new byte[1024*1024];//定义中间缓冲区容器,因为mp3文件有近5M,所以按每兆来划分一部分
63         int len=0;
64         int count=0;//定义量词   用于命名 即第几部分
65         while((len=fis.read(buf))!=-1)//读写操作
66         {
67             
68             fos=new FileOutputStream("c:\\splitfiles\\"+count+++".part");
69             fos.write(buf);//写入
70             fos.close();//关闭输出流资源
71             
72         }
73         fis.close();//关闭输入流资源
74     }
75 }

ps:将图片文件切割成多部分时,如果将其保存成图片格式,查看时显示文件损坏。

  将音乐文件切割成多部分时,如果将其保存成图片格式,点击依旧可以听到部分截取的音乐