黑马程序员_I/O流(递归、配置文件、流的合并拆分)

---------- 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)。

---------- android培训java培训、java学习型技术博客,期待与您交流!----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值