今天项目练习的时候遇到一个需要复制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相关知识的理解不够,还未能得出其原因。比较遗憾。