day20(下)_IO流5(递归穷举与删除,Properties,PrintStream,PrintWriter,SequenceInputStream)

news/2023/6/5 21:56:43

 

1.对目录和文件递归穷举

/*
列出指定目录下的文件或者文件夹,包含子目录中的内容
也就是列出目录下所有的内容
例如:new File(d:\\);在d盘下还有一个abc目录而abc下还有文件和目录,而用list()方法只能获取到d盘下的文件和目录
*/
package filedemo;
import java.util.Arrays;
import java.io.File;class FileFilterDemo2{/*采用了递归(重复调用使用自身功能),即首先遍历该目录下所有文件/目录一旦遍历到目录,在调用自身进行遍历.*/public static String level(int n){StringBuilder sb=new StringBuilder();sb.append("|-");while((n--)!=0)sb.insert(0," ");//不断的向"|-"前插入空格return sb.toString();}public static void getFiles(File f,int level){System.out.println(level(level)+f);level++;//递归调用为下一级目录File[] dirFiles=f.listFiles();//获取到该目录下所有的文件和目录,其中File对象都采用File(File parent,String child)构造if(dirFiles==null||dirFiles.length==0)//说明传入的pathName不表示目录或目录为空,那么不需要遍历return;elsefor(File file : dirFiles){if(file.isDirectory())//当file中的对象的child依然是目录接着遍历
                getFiles(file,level);elseSystem.out.println(level(level)+file);}}public static void main(String[] args){getFiles(new File("f:\\a"),0);}
}

_thumb1

关于递归注意事项:

/*
递归注意:一定要有出口(也就是限定条件),不然相当于死循环递归次数过多,会导致OutOfMemoryError(内存溢出)
*/
class RecursionTest{/*十进制->二进制*/public static void toBin(int num){if(num>0){toBin(num/2);System.out.print(num%2);}}/*求前n项和*/public static int getSum(int n){if(n==1)return 1;elsereturn n+getSum(n-1);}public static void main(String[] args){toBin(10);System.out.println("\n"+getSum(80000));//不断在内存中开辟空间->OutOfMemoryError(内存溢出) }
}

2.递归删除指定目录:

/*删除一个带内容的目录删除原理:在windows中,删除目录从目录里面往外删除从里往外删->递归
*/
package filedemo;
import java.io.File;
class RemoveDir{public static void removeDir(File f){File[] allFile=f.listFiles();if(allFile==null||allFile.length==0)//空文件夹/文件 直接删除
       System.out.println(f.delete());else{//遍历到最内层->删除,删除完内层->逐步往外删for(File files : allFile){if(files.isFile())System.out.println(files.delete());elseremoveDir(files);}System.out.println(f.delete());//当for执行完,说明该目录下文件已经全部删除,需要删除该目录 
      }}public static void main(String[] args){removeDir(new File("h:\\a"));}
}

对于运行结果,(依然是上面遍历的测试目录)会删除9次,会有9个boolean值并且必须都为true,否则可能为同一个文件/目录多次删除

_thumb

3.File练习:

/*获取到指定目录中所有java文件的路径,并输出到一个文件中.
思想:
①对目录进行递归搜索
②对于文件只要以.java结尾文件
③把.java文件路径存入ArrayList集合中.*/
package filedemo;
import java.io.File;
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
class JavaFilesList{public static void getJavaFiles(File dir,List<File> list){File[] files=dir.listFiles();if(files!=null && files.length!=0)for(File f : files)if(f.isDirectory())getJavaFiles(f,list);elseif(f.getName().endsWith(".java"))list.add(f);}public static void writeFile(List<File> list,String javaListFile){BufferedWriter bfw=null;File[] javaFiles=list.toArray(new File[list.size()]);//集合转数组try{bfw=new BufferedWriter(new FileWriter(javaListFile));for(File f : javaFiles){bfw.write(f.getAbsolutePath());//获取到绝对路径写入,list存入File对象不一定封装的是绝对路径,可能是相对路径
      bfw.newLine();bfw.flush();}bfw.write("一共"+list.size()+"个java文件");}catch(IOException e){throw new RuntimeException("写文件异常");}finally{try{if(bfw!=null)bfw.close();}catch(IOException e){throw new RuntimeException("关闭流异常");}try{Runtime.getRuntime().exec("notepad.exe "+javaListFile);//写完后,自动用记事本打开查看内容
    }catch(IOException e){e.printStackTrace();}}}public static void main(String[] args){    List<File> list=new ArrayList<File>();getJavaFiles(new File("g:\\JavaCode"),list);System.out.println(list.size());writeFile(list,"f:\\JavaFiles.txt");//写入文件
    }
}

将制定文件夹从源路径复制到目的路径下:

/*
采用递归方法遍历文件夹中的内容
例如:C:\s\abc->d:\ 将abc文件夹及文件夹的所有文件/文件夹拷贝到d盘下AbsolutePath
abc         1.txt      ->d:\abcdef        ->d:\abc\ def2.txt    ->d:\abc\def\ 2.txtghk      ->d:\abc\def\ ghk3.txt  ->d:\abc\def\ghk\ 3.txtmnl        ->d:\abc\mnl
*/
/*
递归过程:1.                      src: c:\s\abc dest: d:\dest<-d:\abc 创建abccopyFile(c:\s\abc\1.txt,d:\abc\1.txt)copyDir(c:\s\abc\def,d:\abc)
2.src:c:\s\abc\defdest:d:\abcdest<-d:\abc\def 创建defcopyFile(c:\s\abc\def\2.txt,d:\abc\def\2.txt)copyDir(c:\s\abc\def\ghk,d:\abc\def)
3....
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
class CopyDirectory{public static void copyFile(File src,File dest)throws IOException{FileInputStream fis=new FileInputStream(src);FileOutputStream fos=new FileOutputStream(dest);byte[] byteArr=new byte[1024*1024];int bytes=0;while((bytes=fis.read(byteArr))!=-1)fos.write(byteArr,0,bytes);fis.close();fos.close();}public static void copyDir(File src,File dest)throws IOException{File[] files=src.listFiles();dest=new File(dest.getPath()+"\\"+src.getName());//例如:第一次 创建 d:+\+abcdest.mkdir();                               //     第二次 创建 d:\abc +\+ deffor(File f : files)if(f.isFile())copyFile(new File(f.getAbsolutePath()),new File(dest.getPath()+"\\"+f.getName()));//例如:当遍历到1.txt时 //C:\s\abc\1.txt,d:\abc\1.txtelse//对于文件夹操作copyDir(new File(f.getAbsolutePath()),dest);//例如:当遍历到def时//C:\s\abc\def,d:\abc
    } public static void main(String[] args)throws IOException{copyDir(new File("C:\\s\\abc"),new File("d:\\"));//abc文件夹以及文件夹中的内容拷贝到D盘下
                                             System.out.println(new File("d:\\def\\"+"\\"+"\\"+"abc").getPath());System.out.println(new File("d:\\def\\"+"abc"));
/*
以上两者结果相同(d:\def\abc),也就是说文件系统中会去除多余的\,但是d:\\与d:结果不同,一个为d:\\,一个为d:
*/}}

4.Properties类方法:

/*
在System类中的获取系统属性用到PropertiesProperties 类表示了一个持久的属性集。
Properties 可保存在流中或从流中加载。
属性列表中每个键及其对应值都是一个字符串。 该集合是和IO技术相结合的集合容器
该对象特点:可以用于键值对形式的配置文件(.ini)
在加载数据时,需要数据有固定格式:Key=Value
*/
package propertydemo;
import java.util.Properties;
import java.util.Set;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.IOException;
class PropertiesDemo{/*自定义方法将文件中的数据存储到Properties集合中该文件中的数据是以键值对形式存在例如:info.txt: zhangsan=18lisi=25...*/public static void storeInProperties()throws IOException{BufferedReader bfr=new BufferedReader(new FileReader("info.txt"));Properties pro=new Properties();String line=null;while((line=bfr.readLine())!=null)if(!line.startsWith("#")){//注释信息不再加入集合String[] keyValue=line.split("=");//以"="分割pro.setProperty(keyValue[0],keyValue[1]); }System.out.println(pro);bfr.close();}/*利用Properties中的load方法完成void load(InputStream inStream) 从输入流中读取属性列表(键和元素对)。 void load(Reader reader) 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。*/public static void storeInProperties_2()throws IOException{FileReader fr=new FileReader("info.txt");Properties pro=new Properties();pro.load(fr);System.out.println(pro);pro.list(System.out);// void list(PrintStream out)//将属性列表输出到指定的输出流。/*  此时如果改变了键值对信息,但是改变后的信息依然在内存中,如果想把改变反映到文件中,需要用到store方法*/pro.setProperty("zhangsan","30");System.out.println(pro);FileWriter fw=new FileWriter("info.txt");pro.store(fw,"heihei");//heihei为注释信息//在文件中为#heihei
     fr.close();fw.close();}/*Properties存储和获取方法*/public static void propertiesMethodDemo(){Properties prop=new Properties();prop.setProperty("zhang","15");//底层在使用HashTable<Object,Object>的put方法prop.put("li","30");System.out.println(prop);Set<String> names=prop.stringPropertyNames();//返回Key的set集合for(String n : names)System.out.println(n+"="+prop.getProperty(n));}public static void main(String[] args)throws IOException{propertiesMethodDemo();System.out.println();storeInProperties();System.out.println();storeInProperties_2();} 
}

Properties_thumb

5.Properties的load与store练习:

/*
需求:用于记录应用程序运行次数.如果使用次数已到,那么给出注册提示.
分析:很容易想到的是:计数器可是该计数器
用程序的退出,该计数器也在内存中消失了
下一次在启动该程序,又重新开始从0计数.
这样不是所需要的程序即使结束,该计数器的值也存在
下次程序启动会先加载该计数器的值
并+1后重新存储起来所以需要建立一个配置文件.用于记录软件使用次数该配置文件使用键值对的形式
这样便于阅读数据,并操作数据键值对数据是map集合.
数据是以文件形式存储,使用io技术
那么map+io-->properties配置文件可以实现应用程序数据共享
*/
package propertiestest;
import java.util.Properties;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
class PropertiesTest{/*每次程序运行获取使用次数(counts),并在获取完之后,++counts存入到配置文件中*/public static void checkCounts()throws IOException{ File f=new File("set.ini");Properties pro=new Properties();if(!f.exists())//文件第一次不存在需要创建
   f.createNewFile();FileReader fr=new FileReader(f);pro.load(fr);int count=0;
String value=pro.getProperty("counts");
if(value!=null)//新建文件中没有counts,此时不再获取,只写count=Integer.parseInt(pro.getProperty("counts"));if(count>=3){//该软件只能够使用三次System.out.println("免费次数已用完");return;//>=3不再写入直接返回
 }FileWriter fw=new FileWriter(f);
pro.setProperty("counts",(++count)+"");
pro.store(fw,"number of use"); 
fr.close();
fw.close();
/*关于pro.store():所有写入各个项后,刷新输出流(内部在把属性集写入输出流后调用了flush)此方法返回后,输出流仍保持打开状态。 但没有关闭写入流
*/}public static void main(String[] args)throws IOException{checkCounts();}
}
/*
注意:①配置文件不存在,需要创建②需要写入键值对*/

6.PrintStream与PrintWriter

/*
打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印
字节打印流:PrintStreamPrintStream(File file) file-同下PrintStream(String fileName) fileName -要用作此打印流目标的文件名称。如果存在该文件,则将其大小截取为零;否则,创建一个新文件。将输出写入文件中,并对其进行缓冲处理。 PrintStream(OutputStream out) 字符打印流:PrintWriter
PrintWriter(File file) 
PrintWriter(OutputStream out)
根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。此便捷构造方法创建必要的中间 OutputStreamWriter,后者使用默认字符编码将字符转换为字节。
  
PrintWriter(String fileName) 
PrintWriter(Writer out)//比PrintStream多了一个可以接收字符输出流的构造函数
*/
package printdemo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.FileWriter;
class PrintStreamDemo{public static void main(String[] args)throws IOException{BufferedReader bufr =new BufferedReader(new InputStreamReader(System.in));//PrintWriter out=new PrintWriter(System.out);//PrintWriter通用性比较强,在写入流后,需要刷新
     /*
          System.out在内部会被封装为new BufferedWriter(new OutputStreamWriter(System.out))
     *///PrintWriter out=new PrintWriter(System.out,true);//autoFlush-boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区,下面由于用到println所以可以不用out.flushPrintWriter out=new PrintWriter(new FileWriter("PrintWriter.txt"),true);//true含义同上,这样写可以把new FileWriter中的数据刷新到文本中,而不用在out.flush  
                       String line=null;while((line=bufr.readLine())!=null){out.println(line);//将值打印初始化的流对象中//out.flush();//刷新的是初始化时的流对象
     }bufr.close();out.close();}
}

7.SequenceInputStream:

/*
SequenceInputStream(顺序输入流):表示其他输入流的逻辑串联。它从输入流的有序集合开始, 并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。 
该类的由来:例如:已知:四个文件:src1.txt,src2.txt,src3.txt,dest.txt;需求:把前三个文件中数据写入到dest.txt中分析:src1.txt--->FileReader("src.txt")--->FileWriter("dest.txt",true)-->dest.txtsrc2.txt,src3.txt同理    每个源和目的需要单独的IO流对象操作,非常麻烦SequenceInputStream作用:对多个源依次操作,更加方便.*/
package sequenceinputstream;
import java.io.*;
import java.util.*;
class SequenceDemo{public static void main(String[] args)throws IOException{/*SequenceInputStream(Enumeration<? extends InputStream> e) 该构造函数形参为枚举->集合Vector<E>的elements返回Enumeration<E>*/    Vector<FileInputStream> vector=new Vector<FileInputStream>();vector.add(new FileInputStream("f:\\src1.txt"));vector.add(new FileInputStream("f:\\src2.txt"));vector.add(new FileInputStream("f:\\src3.txt"));Enumeration<FileInputStream> en=vector.elements();SequenceInputStream sis=new SequenceInputStream(en);BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("f:\\dest.txt"));//FileOutputStream fis=new FileOutputStream("f:\\dest.txt");int aByte=0;//byte[] b=new byte[1024];while((aByte=sis.read())!=-1){bufos.write(aByte);bufos.flush();}/*int bytes;while((bytes=sis.read(b))!=-1)fis.write(b,0,bytes); }*/bufos.close();sis.close();}
}

 

文件切割和合并综合练习:

/*
切割文件:其实就是一个源(该文件)对应多个目的(多个碎片文件)
切割①需要一个输入流对象关联该文件②为了控制每次读取大小,自定义一个缓冲(数组)③循环读取,每次读取将读取的数据,通过输出流写入一个文件中,直至源文件末尾(-1)
合并多个源对应一个目的,这里可以采用SequenceInputStream
*/import java.io.FileInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Iterator;
class SplitFileTest{/*当文件不太大时,指定的缓冲区可以为分割的文件大小*/public static void splitFile_1(String file)throws IOException{/*以切割图片为例*/FileInputStream fis=new FileInputStream(file);byte[] b=new byte[1024*1024];//每次最多分割1MBFileOutputStream fos=null;int bytes=0,count=1;while((bytes=fis.read(b))!=-1){fos=new FileOutputStream("f:\\part"+(count++)+".part");//每次新建一个流对象关联一个新的文件  fos.write(b,0,bytes); fos.close();//每次循环关闭上次的流对象
   }fis.close();}
 /*
当文件特别大(例如2GB),而需要按400MB分割,不建议定义400MB缓冲区,定义小点缓冲区40MB,使切割文件满足制定大小*/public static File[] splitFile_2(File f)throws IOException{FileInputStream fis=new FileInputStream(f);byte[] byteArr=new byte[1024*1024];ArrayList<File> arrList=new ArrayList<File>();int bytes=0;int count=0;File wf=null;FileOutputStream fos=null;while((bytes=fis.read(byteArr))!=-1){if(wf==null||wf.length()==2*1024*1024){if(fos!=null)fos.close();//关闭与上一个文件相关联的写入流对象wf=new File("C:\\Users\\ZhangHongQ\\Desktop\\java复习\\"+(++count)+".part");arrList.add(wf);fos=new FileOutputStream(wf);}fos.write(byteArr,0,bytes);}fis.close();return arrList.toArray(new File[arrList.size()]);}/*对以上分割的文件进行合并*/public static void mergeFile(File[] file)throws IOException{ArrayList<FileInputStream>al=new ArrayList<FileInputStream>();for(File f : file)al.add(new FileInputStream(f));final Iterator<FileInputStream>it=al.iterator();SequenceInputStream sis=new SequenceInputStream(new Enumeration<FileInputStream>(){public boolean hasMoreElements(){return  it.hasNext();}public FileInputStream nextElement(){return it.next();}});FileOutputStream fos=new FileOutputStream(new File("C:\\Users\\ZhangHongQ\\Desktop\\java复习\\Bandari.mp3"));int aByte=0;while((aByte=sis.read())!=-1)fos.write(aByte);sis.close();fos.close();}public static void main(String[] args)throws IOException{File[] file=splitFile_2(new File("F:\\SONG\\Bandari - 爱尔兰风笛.mp3"));//例如:8.93MB的MP3文件System.out.println(Arrays.toString(file));//2MB 2MB 2MB 2MB 934KB
    mergeFile(file);}
}

转载于:https://www.cnblogs.com/yiqiu2324/archive/2013/05/30/3108795.html


https://dhexx.cn/news/show-18555.html

相关文章

android javacv 录像,使用JavaCV(ffmpeg)录制视频

使用JavaCV(ffmpeg)录制视频JavaCV是对各种常用计算机视觉库的封装后的一组jar包&#xff0c;其中封装了ffmpeg、OpenCV、libdc1394、OpenKinect、videoInput和ARToolKitPlus等计算机视觉编程人员常用库的接口&#xff0c;可以通过其中的utility类方便的在包括Android在内的Jav…

协方差矩阵和相关矩阵

1、协方差矩阵 协方差是衡量两个随机变量&#xff08;同一样本&#xff0c;不同分量&#xff09;的相关程度。&#xff08;方差描述的是一维变量&#xff09;随机变量 之间的协方差可以表示为根据已知的样本值可以得到协方差的估计值如下&#xff08;列向量相关&#xff09;&am…

6.链路层和局域网

链路层链路层的主体是网络适配器&#xff0c;也称为网络接口卡2. 变换局域网链路层交换机的任务是在主机和路由器之间承载数据报没有两个适配器有相同的MAC地址适配器到哪里&#xff0c;MAC地址都不会改变主机移动时&#xff0c;主机的IP地址需要随之改变&#xff0c;以改变连接…

Google开发的QRcode二维码生成和解码及最大容量

1.源码 package com.test; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingExcep…

网页自动加拼音html,HTML5给汉字加拼音收起展开组件的实现代码

来看看 HTML 的历史和规范常识。HTML 规范是 W3C 与 WHATWG 合作共同产出的&#xff0c;HTML5 因此也不例外。其中&#xff1a;W3C 指 World Wide Web ConsortiumWHATWG 指 Web Hypertext Application Technology Working Group说好听了是“合作产出”&#xff0c;但其实更像是…

VS2012在一个解决方案中添加多个项目(工程)

首先要肯定的一点是&#xff0c;在一个解决方案&#xff08;solution&#xff09;中是可以添加多个项目&#xff08;project&#xff09;的&#xff0c;这多个项目之间存在两种关系&#xff1a;1.项目间彼此独立&#xff0c;各自有各自的入口&#xff0c;只是组织在一个解决方案…

jsp页面中html字段,字符串中的html代码中夹杂了jsp代码,如何独立显示jsp的部分...

图片中的圈圈就是我的问题&#xff0c;两个form表单&#xff0c;第二个表单是我动态生成的。生成的代码如下:if(para.dragDrop){// 创建带有拖动的htmlhtml ;html ;html ;html ;html ;html ;html 点击选择文件;html ;html ;html ;html 或者将文件拖到此处…

Android Develop Training中文翻译04《Running Your App》

《运行你的应用》 通过钱一节课 创建了一个Android项目&#xff0c;项目里有一个默认的”HelloWorld“源文件&#xff0c;它让您可以立即运行的应用程序。 运行应用需要两个条件&#xff1a;是否有一个Android设备和是否使用Eclipse。本节课将会教使用Eclipse和命令行两种方式在…

Sharding-JDBC 分库分表-分页查询优化方案

Sharding支持分页查询的数据库&#xff1f; &#xff08;1&#xff09;完全支持MySQL、PostgreSQL和Oracle的分页查询; &#xff08;2&#xff09;SQLServer由于分页查询较为复杂&#xff0c;仅部分支持。 Sharding-JDBC分页修正 从多个数据库获取分页数据与单数据库的…

1965: [Ahoi2005]SHUFFLE 洗牌 - BZOJ

Description 为了表彰小联为Samuel星球的探险所做出的贡献&#xff0c;小联被邀请参加Samuel星球近距离载人探险活动。 由于Samuel星球相当遥远&#xff0c;科学家们要在飞船中度过相当长的一段时间&#xff0c;小联提议用扑克牌打发长途旅行中的无聊时间。玩了几局之后&#x…