---------- android培训、java培训、java学习型技术博客,期待与您交流!----------
本篇学习内容涉及到File类中的诸多方法,稍加说明后就不再赘述。
File类作为操作文件的类,常见方法可以分为四部分。创建,包括:createNewFile()不覆盖的创建文件;mkdir()创建文件夹;mkdirs()创建多级文件夹。删除,包括:delete()常规删除;deleteOnExit()程序退出时删除指定文件。判断,包括:exist()是否存在判断;isFile()是否是标准文件判断;isDirectory()是否是目录判断;isHidden()是否是隐藏文件判断;isAbsolute()是否为绝对路径名判断。获取信息,包括:getName()获取文件或目录的名称;getPath()获取路径名;getParent()获取父路径名;getAbsolutePath()获取绝对路径名;lastModified()获取文件最后一次修改时间;length()获取文件的长度。
为了完成某种功能,函数需要自身调用自身,这种表现形式或者说编程手法就称为递归。由于递归的特性,除了要限定条件外,还需要注意递归的次数控制,避免内存溢出问题的发生。下面以完成“删除一个带内容的目录”需求的程序来演示,由于在windows系统中,删除目录是由里到外逐层实现的,因此就需要用到递归。
import java.io.*;
class RemoveDir{
public static void main(String[] args){
File dir = new File("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());
}
}
递归的原理其实并不难理解,简单来说就是:从外层由条件引导至最内层,从最内层开始计算逐步回推至最外层。
配置文件是现实当中软件使用必不可少的一个工具,它往往以Properties类来构建。Properties是Hashtable的子类,因此它具备了Map集合的特点。Properties是集合中与IO技术相结合的集合容器,可以作用于键值对配置形式的文件。现实生活中,付费软件试用期计算很常见,其中就用到了配置文件记录,下面就以对其简单模拟的程序来演示Properties类的使用。
import java.io.*;
import java.util.*;
class RunCount{
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
File file = new File("count.ini");
if(!file.exists())
file.createNewFile();
FileInputStream fis = new FileInputStream(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 = new FileOutputStream(file);
prop.store(fos,"");
fos.close();
fis.close();
}
}
操作流程并不复杂。用文件读取流FileInputStream和配置文件相关联(如配置文件不存在,事先先创建),然后用Properties对象对键值对数据进行获取与修改,最后通过文件写入流FileOutputStream将键值对数据重新写入配置文件进行保存。
在对数据流的操作过程中,往往需要对多个数据流进行连续操作,反复创建和关闭流显然不方便,这就涉及到了流的合并拆分问题。先来看下面这个示例:
import java.io.*;
import java.util.*;
class SplitFile{
public static void main(String[] args) throws IOException {
// splitFile();
merge();
}
public static void merge() throws IOException {
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++){
al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
public boolean hasMoreElements(){
return it.hasNext();
}
public FileInputStream nextElement(){
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void splitFile() throws IOException {
FileInputStream fis = new FileInputStream("c:\\1.bmp");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while((len=fis.read(buf))!=-1){
fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
上述代码演示的是一个.bmp图片文件的拆分与合并。如你所见,拆分时以1m大小为界,完成这一步骤,只需要每次读取1m的流中数据后就将其写入一个碎片文件即可。而要完成合并,就需要用到序列流SequenceInputStream了。在此例子中,由于要合并三个流,因此所用的构造方法是SequenceInputStream(Enumeration<? extends InputStream> e)。