有关文件相关操作的方法汇总

有关文件的方法汇总:

指定目录下显示一级子目录信息

中心说明:该任务重在显示格式的设置上

主要涉及:File类中listFiles()方法,其返回值类型为File对象数组;isFile()或者isDirectory()方法;lastModified()获取文件最后修改时间;getName()获取文件名;NumberFormat的子类DecimalFormat(“自定义显示格式”)用于对文件大小显示进行格式化处理;String类中substring(起始索引,结束索引(不含))方法对文件名显示长度的处理可以使得各文件有对齐效果。

/**
	 * 根据提供的目录,显示目录下子文件或子目录的信息
	 * FileItem为包含自定义文件各属性的类
	 * @param dir
	 */
	public ArrayList<FileItem> showList(File dir) {
		//以下集合不适合设为全局变量
		ArrayList<FileItem> list = new ArrayList<FileItem>();
		// 获取目录下所有的File对象
		File[] files = dir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				//获取目录中的一个File对象
				File f = files[i];
				//将File转换为FileItem
				FileItem fi = converter(f, i);
				list.add(fi);
			}
		}
		return list;
	}
	
	private FileItem converter(File f, int num) {
		FileItem item = new FileItem();
		item.setNum(num + 1);
		item.setName(f.getName());
		item.setType(f.isFile() ? "文件" : "目录");
		item.setLastModipy(new Date(f.lastModified()));
		//获取文件的大小
		if(f.isFile()) {
			//获取标准文件的大小
			long size = f.length();
			String fileSize = formatSize(size);
			item.setSize(fileSize);
		}

		return item;
	}
	
	/**
	 * 以固定格式显示文件字节大小
	 * @param size
	 * @return
	 */
	private String formatSize(long size) {
		if(size<1024) {
			return size+"字节";
		}else {
			NumberFormat fmt = new DecimalFormat("#,###KB");
			return fmt.format(size/1024);
		}
	}
	
	FileItem类中:
	@Override
	public String toString() {
		DateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss SSS");
		String time = fmt.format(lastModipy);
		if(name.length()>2) {
			name = name.substring(0,1)+"···";
		}
		return num +"\t"+name+"\t"+type+"\t"+time+"\t"+size;
	}

多级目录展示

中心说明:该任务要对指定目录下进行彻底的遍历,并按子目录等级显示各目录名称,主要难点为递归的设计和级数标记的设置。

涉及:循环嵌套使用

public void readDir(File f,int n) {
		//n初始传递值为0,每递归1次表示目录级数增加1层(不可放到for循环内部)
		n++;
		if(f.isDirectory()) {
			for (int i = 0; i < f.listFiles().length; i++) {
				
				for (int j = 0; j < n; j++) {
					System.out.print("--");
				}
				
				System.out.println(f.listFiles()[i].getName());
				
				if(f.listFiles()[i].isDirectory()) {
					readDir(f.listFiles()[i],n);
				}
			}
		}
	}

文件或(多级)目录的删除

中心说明:在文件递归的同时考虑File类delete()方法的使用,该方法只能对标准文件和空文件夹进行删除。

涉及:递归循环,delete()方法

import java.io.File;

/**
 * 删除文件/目录
 * @author dell
 *
 */
public class DelDir {
	
	public void delTex(File f) {
		File[] filess = f.listFiles();
		if(filess != null) {
			for (int i = 0; i < filess.length; i++) {
				File fi = filess[i];
				if(fi.isFile()) {
					System.out.println("删除文件"+"\t"+fi.getName());
					fi.delete();
				}else {
					delTex(fi);
				}
			}
		}
		System.out.println("删除目录"+"\t"+f.getName());
		f.delete();
	}

拷贝单个标准文件

中心说明:主要利用InputStream和OutputStream流,下例中由于finally语句块里需对IO流进行关闭操作,因此本在try语句块中对IO流进行的声明放到了try语句块的外层了。

/**
	 * 拷贝单个标准文件
	 * @param sourceFile 源文件
	 * @param targetDir 目标拷贝至文件
	 */
	public static void copyFile(File sourceFile, File targetDir) {
		//判断目标文件是否存在,若不存在创建
		if(!targetDir.exists()) {
			targetDir.mkdirs();
		}
		//根据提供的源文件文件名,结合目标目录构建一个目标文件对象
		File target = new File(targetDir,sourceFile.getName());
		
		InputStream is = null;
		OutputStream os = null;
		try {
			is = new FileInputStream(sourceFile);
			os = new FileOutputStream(target);
			byte[] b = new byte[1024];
			int len = 0;
			System.out.println("开始拷贝...");
			while((len = is.read(b)) != -1) {
				//将读取的字节数组从0开始写入len个字节到目标文件
				os.write(b, 0, len);
			}
			System.out.println("拷贝完成");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				//Closeable接口(jdk1.5)
				if(Objects.nonNull(os)) {
					os.close();
				}
				if(Objects.nonNull(is)) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

RandomAccessFile实现文件拷贝

中心说明:该方法功能与上一个方法拷贝功能完全一样,只是为了应用到RandomAccessFile流即可读入又可输出(“r”和“rw”)的特点,对于实在不想找输入流输出流的时候可以用用,至少复制粘贴是可以安排的。不同的是这里目标文件放的是完整类路径,上一个方法放的是目录路径,这里也无需担心该文件不存在会不会出问题,因为存在的话会覆盖原文件内容,不存在的话,在拷贝过程中,程序会自行进行创建。

/**
	 * 使用RandomAccessFile实现文件拷贝
	 * @param args
	 * @throws IOException
	 */
	public void copy() throws IOException {
		//源文件
		File source = new File("");
		//目标文件
		File target = new File("");
		RandomAccessFile rafSource = new RandomAccessFile("源文件完整路径","r");
		RandomAccessFile rafTarget = new RandomAccessFile("目标文件路径","rw");
		//拷贝过程
		System.out.println("开始拷贝");
		byte[] b = new byte[1024];
		int pos = 0;
		while((pos = rafSource.read(b)) != -1) {
			String s = new String(b,0,pos);
			rafTarget.writeChars(s);
			System.out.println(s);
		}
		rafSource.close();
		rafTarget.close();
		System.out.println("拷贝完成!");
		
	}

拷贝目录

/**
	 * 拷贝目录(目录下包含多级子目录和文件)
	 * 
	 * @param source
	 * @param targetDir 目标目录
	 */
	public static void copy(File source, File targetDir) {
		//判断源文件是否是标准文件
		if (source.isFile()) {
			//如果源文件是标准文件,则直接进行文件拷贝
			copyFile(source, targetDir);
		}else {
			//在目标目录下创建一个跟源目录同名的子目录(未创建)
			targetDir = new File(targetDir,source.getName());
			//如果目标目录不存在则创建
			if(!targetDir.exists())targetDir.mkdirs();
			File[] subFiles = source.listFiles();
			//获取源目录下所有的子文件
			if(subFiles != null) {
				//遍历所有的子文件
				for(int i = 0;i<source.length();i++) {
					copy(subFiles[i],targetDir);
				}
			}
		}
	}

文件监听(是否有发生修改,若修改则返回文件被修改的时间)

中心说明:与下一个方法(线程)可同时进行,线程之间完成情况上互不影响,由于是监听机制,都用了while(true)死循环实现,通过sleep(毫秒数)的使用设置监听结果反馈间隔时间。

import java.io.File;

public class FileListener extends Thread{
	private File target;
	private long lastModify;
	
	public FileListener(File target) {
		this.target = target;
	}
	
	public void run() {
		lastModify = target.lastModified();
		System.out.println("开始监控:"+Tools.getFmtTime(lastModify));
		while(true) {
			long newTime = target.lastModified();
			if(newTime != lastModify) {
				System.out.println("文件被修改,修改时间:"+Tools.getFmtTime(newTime));
				lastModify = newTime;
			}
			try {
				sleep(15000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

对一级子目录下全是标准文件的目录进行监听

import java.io.File;
import java.time.LocalDateTime;

public class DirListener extends Thread{
	private File dir;
	private File[] files;
	
	public DirListener(File dir) {
		this.dir = dir;
	}
	
	public void run() {
		files = dir.listFiles();
		System.out.println("开始监控目录"+LocalDateTime.now());
		while(true) {
			File[] newFiles = dir.listFiles();
			if(newFiles.length != files.length) {
				for(File f:newFiles) {
					boolean flag = true;
					for(File f2:files) {
						if(f.getName().equals(f2.getName())) {
							flag = false;
						}
					}
					if(flag) {
						System.out.println("新文件产生:"+f.getName()+" "+Tools.getFmtTime(f.lastModified()));
					}
				}
				files = newFiles;
			}
			try {
				sleep(15000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

拷贝文件同时显示文件拷贝完成进度

中心说明:主要将显示拷贝进度的线程设置为拷贝文件线程的守护线程,特点在于当拷贝任务完成时,其守护线程(进度显示)线程也将停止。

涉及:setDaemon(true)调用该方法设置为守护线程,在那个线程里设置的就为哪个线程的守护线程。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.NumberFormat;

public class FileCopyByThread extends Thread{

	private File source;
	private File target;
	/**文件总大小*/
	private double totalSize;
	/**当前已拷贝大小*/
	private double currentSize;
	
	public FileCopyByThread(File source, File target) {
		super();
		this.source = source;
		this.target = target;
	}

	@Override
	public void run() {
		try(
				FileInputStream fis = new FileInputStream(source);
				FileOutputStream fos = new FileOutputStream(target);
			){
				//获取文件的实际大小
				totalSize = source.length();
				byte[] b = new byte[1024];
				int len = 0;
				//int read() 读取一个字节,返回是字节内容
				//int read(byte[] b) 将读取的数据装入字节数组,返回真实读取长度
				System.out.println(getName()+"开始拷贝:"+source.getName());
				//创建并启动进度监控的线程
				ProgressListener pl = new ProgressListener();
				//设置当前线程为守护线程
				pl.setDaemon(true);
				pl.start();
				while((len = fis.read(b)) != -1) {
					fos.write(b, 0, len);
					//每次循环类增已拷贝的字节
					currentSize += len;
				}
				System.out.println(getName()+"拷贝完成!");
			}catch (IOException e) {
				e.printStackTrace();
			}
	}
	
	/**
	 * 	计算文件拷贝的线程
	 * @author mrchai
	 */
	class ProgressListener extends Thread{
		@Override
		public void run() {
			while(true) {
				//计算进度
				double d = currentSize / totalSize;
				//将浮点进度格式化为百分比
				String progress = NumberFormat.getPercentInstance().format(d);
				System.out.println("拷贝进度------->"+progress); 
				try {
					sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		
		File source = new File("源文件");
		
		File target = new File("目标文件");
		//启动文件拷贝线程
		new FileCopyByThread(source, target).start();
	}
}

4个线程同步拷贝一个文件

中心说明:应用RandomAccessFile流可以自由设置其读取/写出的指针位置对文件分割拷贝。

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class FileSpitCopy extends Thread{
	
	private File source;
	private File target;
	private long start;
	private long end;
	
	public FileSpitCopy(File source, File target, long start, long end) {
		super();
		this.source = source;
		this.target = target;
		this.start = start;
		this.end = end;
	}

	public void run() {
		try (
				RandomAccessFile read = new RandomAccessFile(source,"r");
				RandomAccessFile write = new RandomAccessFile(target,"rw");
		){
			read.seek(start);
			write.seek(start);
			int count = 0;
			byte[] b =new byte[1024];
			int len = 0;
			while((len = read.read(b)) != -1) {
				write.write(b,0,len);
				count += len;
				if(count >= (end-start)&& !"t3".equals(getName())) {
					break;
				}
			}
			System.out.println(getName()+"拷贝长度--->"+count);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		File source = new File("源文件");
		File target = new File("目标文件");
		
		long item = source.length()/4;
		for (int i = 0; i < 4; i++) {
			FileSpitCopy fsc = new FileSpitCopy(source,target,i*item,(i+1)*item);
			fsc.setName("t"+i);
			fsc.start();
		}
	}

}

注意事项

1.在进行文件访问时,若传入的是目录路径则会提示拒绝访问导致访问失败。

2.在有关递归调用的方法定义是通常情况下返回值类型设置为void,少部分方法利用返回值,比如下例:

//fib(1)+fib(2)
	public int fib(int n) {
		if (n == 1 || n == 2) {
			return 1;
		}
		return fib(n - 2) + fib(n - 1);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值