复制SD卡上的文件以及一些其他操作

今天项目练习的时候遇到一个需要复制SD卡上文件的需求,于是尝试着写了一个类来实现,代码如下:

package com.jeremy.icampus.utilitys.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;

import android.os.Environment;
import android.text.TextUtils;

/**
 * @author jeremysong
 * 
 */
public class FileUtils {

	/**
	 * SD卡在手机上的根目录
	 */
	private final String SD_DIR;
	/**
	 * 本应用程序在SD卡上的根目录
	 */
	private final String APP_ROOT;

	public FileUtils() {
		super();
		SD_DIR = Environment.getExternalStorageDirectory().getAbsolutePath();
		APP_ROOT = SD_DIR + File.separator + "warcraftcollage";
	}

	/**
	 * 在SD卡上创建一个文件
	 * 
	 * @param fileDir
	 *            SD卡上的子目录
	 * @param fileName
	 *            文件名
	 * @return 创建是否成功
	 */
	public boolean createFile(String fileDir, String fileName) {

		String filePath = APP_ROOT + File.separator + fileDir;

		if (new File(filePath).mkdirs()) {
			return false;
		}

		File file = new File(filePath, fileName);
		if (!file.exists()) {
			try {
				return file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return false;
	}

	/**
	 * 从SD卡上的APP文件夹下读取字符串数据
	 * 
	 * @param fileDir
	 *            SD卡上的APP文件夹子目录
	 * @param fileName
	 *            文件名
	 * @return 读取到的字符串,如果文件不存在或读取出错则返回null
	 */
	public String getFile(String fileDir, String fileName) {

		String filePath = APP_ROOT + File.separator + fileDir + File.separator + fileName;
		File file = new File(filePath);

		if (file.exists()) {
			try {
				return readFileToString(file);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return null;
	}
/**
	 * 获取指定目录中的所有文件名
	 * 
	 * @param fileDir
	 * @return
	 */
	public String[] getFileNames(String fileDir) {

		File file = new File(APP_ROOT, fileDir);

		return file.list();

	}

	/**
	 * 读取文本文件中的文本信息,并返回
	 * 
	 * @param file
	 * @return 如果文件不存在或者读取失败,则返回null
	 * @throws Exception
	 */
	private String readFileToString(File file) throws Exception {

		// byte[] buffer = new byte[512];
		char[] chars = new char[512];
		int len = -1;
		StringBuilder mBuilder = new StringBuilder();

		FileInputStream fis = new FileInputStream(file);
		// 一些中文编码:GBK、GB2312、UTF-8
		InputStreamReader reader = new InputStreamReader(fis, "GB2312");

		do {
			len = reader.read(chars);
			if (len == -1) {
				break;
			}
			mBuilder.append(chars, 0, len);
		} while (true);

		reader.close();
		fis.close();
		return mBuilder.toString();
	}

	/**
	 * 获取SD卡上指定路径中的指定文件
	 * 
	 * @param dir
	 *            SD卡的指定路径
	 * @param name
	 *            指定的文件
	 * @return
	 */
	public File getAppointedFile(String dir, String name) {

		String path = APP_ROOT + File.separator + dir + File.separator + name;
		File file = new File(path);

		return file;
	}

	/**
	 * 复制SD卡上指定的文件到指定的位置
	 * 
	 * @param fromDir
	 *            被复制的文件路径(从SD_ROOT算起)
	 * @param fromName
	 *            被复制的文件名
	 * @param toDir
	 *            将文件复制到的目标目录(从SD_ROOT算起),如果为null,则为源目录下名为copy的子目录
	 * @param toName
	 *            新文件的文件名,如果为null,则与源文件同名
	 * 
	 * @return 复制操作是否成功
	 * @throws NullPointerException
	 *             待复制的文件目录或文件名为空
	 * @throws IOException
	 *             新文件创建失败
	 */
	public boolean copyFile(String fromDir, String fromName, String toDir, String toName) throws NullPointerException, IOException {
		// ----------初始化形参变量---------------------

		// 如果fromDir或fromName为空的话,抛出空指针异常(暂不考虑复制文件夹的情况)
		if (TextUtils.isEmpty(fromDir) || TextUtils.isEmpty(fromName)) {
			throw new NullPointerException("待复制的文件目录及文件名不能为空");
		}
		// 如果toDir为空则在定义toDir为fromDir下的copy文件夹
		if (TextUtils.isEmpty(toDir)) {
			toDir = fromDir + File.separator + "copy";
		}
		// 如果toName为空的话,则定义toName为fromName后加(copy)
		if (TextUtils.isEmpty(toName)) {

			String namePart[] = fromName.split("\\.");
			StringBuilder mBuilder = new StringBuilder();
			for (int i = 0; i < namePart.length - 1; i++) {
				mBuilder.append(namePart[i]);
			}

			String prefixName = mBuilder.toString();
			String suffixName = namePart[namePart.length - 1];

			String name = prefixName + "(copy)." + suffixName;
			toName = name;
		}

		// ---------------判断复制的目的目录是否存在,并作出适应的处理-------------------

		File fDir = new File(APP_ROOT, fromDir);
		File fFile = new File(fDir, fromName);
		// 判断待复制的文件是否存在
		if (!fFile.exists()) {
			throw new FileNotFoundException("待复制的文件不存在");
		}

		File tDir = new File(APP_ROOT, toDir);
		// 判断待复制目的目录是否存在,若不存在则创建该目录
		boolean flag = false;
		if (!tDir.exists()) {
			flag = tDir.mkdirs();
		} else {
			flag = true;
		}
		// 确认复制目的目录已存在,开始复制
		if (flag) {
			File tFile = new File(tDir, toName);
			long fileSize = fFile.length();
			// 创建一个新的的文件
			RandomAccessFile raf = new RandomAccessFile(tFile, "rw");
			raf.setLength(fileSize);
			// 进行复制工作
			FileInputStream fis = new FileInputStream(fFile);
			byte[] buffer = new byte[512];
			int len = -1;
			do {
				len = fis.read(buffer);
				if (len == -1) {
					break;
				}
				raf.write(buffer, 0, len);
			} while (true);

			raf.close();
			fis.close();
			return true;
		}

		return false;
	}

}

在处理上述问题的时候遇到问题是,在使用String类的slipt()方法的时候,字符点【dot(.)】处理纠结了好久。因为如果使用str.slipt(".")的话,是无法分割字符串的。最后查了一下API文档。据描述,点在 正则表达式中的表示有其他的含义,所以导致之前的尝试失败。最后是使用str.slipt("\\.") 成功的获得了期望的效果。可惜的是本人对 正则表达式的了解太少以及java相关知识的理解不够,还未能得出其原因。比较遗憾。

你可能感兴趣的:(复制SD卡上的文件以及一些其他操作)