对字节输入输出流的理解以及几道练习题
关于输入输出流,准确的来将应该是字节输入输出流,我草草总结了一下.使用的xmind思维导入工具(是锁哥给我们的),放上来吧.后续有学习到的话,再去添加修改吧.
1.将一个文件切割之后再合并
分割:将文件按照2M的大小来进行分割
因为要分割成多个文件,所以要设置一个变量,用来动态的生成新的用来存储分割后文件的文件
1 FileInputStream fis = new FileInputStream("D:\\test\\123\\1.mp3"); 2 int name = 1; 3 int len = 0; 4 byte[] b = new byte[1024*1024]; 5 while((len = fis.read(b))!= -1){ 6 FileOutputStream fos = new FileOutputStream("D:\\test\\456\\parts\\" + name + ".mp3"); 7 fos.write(b,0,len); 8 fos.close(); 9 name++; 10 }
合并:将分割下的文件来合并成完整的文件(我这边有8个文件,所以循环8次)
只需要生成一个最终的文件来存储之前的8个碎片
1 //先创建输入流对象,用循环把文件都读入到内存中 2 FileOutputStream fos = new FileOutputStream("D:\\test\\123\\aa.mp3"); 3 for(int i = 1;i <= 8;i++){ 4 byte[] b = new byte[1024*1024]; 5 int len = 0; 6 FileInputStream fis = new FileInputStream("D:\\test\\456\\parts\\" + i + ".mp3"); 7 while((len = fis.read(b))!= -1){ 8 fos.write(b,0,len); 9 } 10 fis.close(); 11 } 12 fos.close();
2.把指定目录下D:\test1(不包含子目录)的所有图片,复制到另一个指定目录下D:\test1\pic(使用文件过滤器来过滤图片)
应用了局部内部类,在以后的使用中会越来越多
注意: 当时解这道题目的时候,对我来说,主要的难点就是复制之后,怎么样生成新的目录,去保存他们
两种办法:
1.使用一个变量n.这个n用来控制复制之后的文件的名字,之后的命名为1,2,3,....jpg
2.使用后来的目的地目录和文件的名字拼接成一个File对象,把之前的文件名字也一并复制过来.
这两种在我下面的代码中都有体现
1 public static void main(String[] args) throws Exception { 2 //先使用过滤器过滤 3 File dir = new File("D:\\test1"); 4 //使用匿名内部类实现构造器 5 File[] names = dir.listFiles(new FileFilter() { 6 7 @Override 8 public boolean accept(File pathname) { 9 //复写accept函数 10 return pathname.isFile() && pathname.getName().endsWith(".JPG"); 11 } 12 }); 13 //name代表的是符合条件的文件的路径,数量是names.length; 14 //使用一个n作为名字的变量的控制器 15 int n =1; 16 for(File name : names){ 17 // if(n >1) 18 // n++; 19 String s = n + ".JPG"; 20 method(name,s); 21 n++; 22 } 23 24 } 25 26 private static void method(File name,String s) throws FileNotFoundException, IOException { 27 //根据具体的name获得对应的输入流对象 28 FileInputStream fis = new FileInputStream(name.getAbsolutePath()); 29 //将输入流对象读入到内存中 30 byte[] b = new byte[1024]; 31 int len = 0; 32 // File file = new File("D:\\test1\\pic\\",name.getName()); 33 File file = new File("D:\\test1\\pic\\",s); 34 FileOutputStream fos = new FileOutputStream(file); 35 while((len = fis.read(b))!= -1){ 36 fos.write(b,0,len); 37 } 38 //System.out.println("1"); 39 fos.close(); 40 }
3.需求:使用文件队列的方式遍历指定目录下(包含子目录)的所有.java文件的路径写入到txt中
使用递归,一层一层的向下遍历
1 public static void main(String[] args) throws Exception { 2 // 3 File dir = new File("D:\\test2"); 4 File dest = new File("D:\\test1\\java.txt"); 5 6 findFolderAndFile(dir,dest); 7 System.out.println("Done"); 8 } 9 10 11 private static void findFolderAndFile(File dir,File dest) throws Exception { 12 //列出目标文件中的所有的文件或文件夹,写过滤器 13 File[] files = dir.listFiles(new FileFilter() { 14 15 @Override 16 public boolean accept(File pathname) { 17 //要获得的是父目录以及其下的子目录,只要满足.java或者是文件夹就可以放行 18 return pathname.isDirectory() || pathname.getName().endsWith(".java"); 19 } 20 }); 21 //对files进行遍历 22 for(File file : files){ 23 if(file.isFile()){ 24 //这个file就是已经找到的符合条件的.java文件.创建输出流输出到目标文件 25 FileOutputStream fos = new FileOutputStream(dest,true); 26 String name = file.getAbsolutePath(); 27 String line_separator = System.getProperty("line.separator"); 28 fos.write((name + line_separator).getBytes()); 29 }else{ 30 findFolderAndFile(file,dest); 31 } 32 } 33 }
4.复制指定目录下的以及子目录子子目录下的文件和文件夹到其他目录下
这道题目解起来也是挺费劲的,中间涉及到的判断比较多.
主要卡住我的点是,因为是复制所有的文件和文件夹以及子目录中的等等,因此没有使用过滤器.
复制的目标路径的获得是一个重点.目标路径中,没有这个文件的话,就要创建这个文件,没有这个文件夹的话,就要创建这个文件夹.通过多层的判断来实现
遍历源目录下所有文件对象
判断每一个文件对象 属于文件 还是文件夹
是文件:
获取文件的父路径,判断父路径是否存在
存在:把源文件写入目标文件中(创建目标文件对象)
不存在:创建父路径,再把把源文件写入目标文件中
是文件夹:
判断文件夹是否存在,存在:不执行任何操作, 不存在:创建文件夹
再次获取源文件夹下所有的文件对象
1 public static void main(String[] args) throws Exception { 2 // 3 File dir = new File("D:\\test1"); 4 File dest = new File("D:\\test3"); 5 6 findFoldersAndCopy(dir,dest); 7 System.out.println("done"); 8 9 } 10 11 private static void findFoldersAndCopy(File dir, File dest) throws Exception { 12 //遍历源文件下所有的文件/文件夹对象 13 File[] files = dir.listFiles(); 14 for(File file : files){ 15 File destFileName = new File(dest,file.getName()); 16 if(file.isFile()){ 17 if(!destFileName.exists()) destFileName.createNewFile(); 18 FileInputStream fis = new FileInputStream(file.getAbsolutePath()); 19 FileOutputStream fos = new FileOutputStream(destFileName); 20 byte[] b = new byte[1024]; 21 int len = 0; 22 while ((len = fis.read(b)) != -1) { 23 fos.write(b, 0, len); 24 } 25 } 26 if(file.isDirectory()){ 27 if(!destFileName.exists()) destFileName.mkdir(); 28 findFoldersAndCopy(file, destFileName); 29 } 30 } 31 32 33 }
以上的这些代码,我很多都没有进行异常的捕获,太多了,比较复杂,不利于解题.因此也就没有写了.
使用输入输出流的过程中,有很多是没有对控制台输出的.后来我为了提示我自己程序完成了,可以在程序的最后加上一道输出语句.例如"Done".也可以执行一些计算运行时长的功能.
关于复制的问题,嗯,比如说,把A文件夹下的a文件--->复制到B文件下.这时的输出流的构造函数中是不能直接写B的路径的,需要给出在B文件夹下的具体哪个文件,文件叫什么名字.
1.new FileInputStream("D:\\test\\1.txt") 输入流中,如果这个1.txt文件是不存在的,那么系统会自动帮忙创建;
2.new FileOutputStream("D:\\test\\1.txt"); 输出流中,如果没有给定1.txt的话,这样是肯定会报错的,系统不知道要将数据写到哪里去.
3.如果是把文件从源文件夹中复制到目标文件夹中,那么在目标文件夹中一定要给定具体的接收复制过来数据的新的文件名称.例如上面的第一题.经过测试,如果不给定的话,会报错.xxxx文件夹没有访问权限.
4.如果是要复制文件夹的话,其中会多一步去创建文件夹的过程.在练习第4题中有体现.