package com.banking.xc.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import skytv_com.banking.enjoymovie.MyApplication;
import android.content.Context;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import com.banking.xc.utils.HttpGroup.StopController;
public class FileService {
private static final String FILE_MODE_WORLD_WRITEABLE = "622";// 外部可写-rw--w--w-
private static final String FILE_MODE_WORLD_READABLE = "644";// 外部可读-rw-r--r--
private static final String FILE_MODE_WORLD_ACCESS = "755";// 外部可执行(访问)drwxr-xr-x
private static final String aplcationDir = "/jingdong";// 定义本应用在SD卡上所使用的文件夹
private static final String SHARE_IMAGE_NAME = "shareimage.jpg";// 供外部应用分享的图片名称
private static final String SYSTEM_OPERATOR = "/";
private static final String TAG = "FileService";
/**
* 最大的图片缓存存储数量
*/
private static final int MAX_IMAGE_SAVE_NUM = 4096;
/**
* 图片缓存数量未知
*/
private static final int UN_KNOW = -20;
/**
* sd卡中的缓存图片数量
*/
private static int sdCardImageCacheNum = UN_KNOW;
/**
* 手机内存中的图片缓存数量
*/
private static int phoneMemoryImageCacheNum = UN_KNOW;
/**
* 后台清理多余图片的线程
*/
private static DeleteOverImageThread deleteOverImageThread;
// 目录类型
public static final int IMAGE_DIR = 1;// 图片缓存目录
public static final int JSON_DIR = 2;//
public static final int CAMERA_DIR = 3;// 摄像头临时图片目录
public static final int PERSIST_DIR = 4;//持久化文件目录
// 对应目录
private static Directory imageDir;
private static Directory jsonDir;
private static int imageDirState;// -1:没有适合存储的空间,0:未定,1:内部存储空间,2:外部存储空间
private static int jsonDirState;// -1:没有适合存储的空间,0:未定,1:内部存储空间,2:外部存储空间
public static boolean isNeedReSetupStorageStateJson = true;// 是否需要重新设置存储标志位,默认为true,应用新启动需要检查
public static boolean isNeedReSetupStorageStateImage = true;// 是否需要重新设置存储标志位,默认为true,应用新启动需要检查
private static final String IMAGE_CHILD_DIR = "/image";// json 子目录
private static final String JSON_CHILD_DIR = "/json";// image 子目录
private static final String CAMERA_CHILD_DIR = "/camera";// camera 子目录
private static final String PERSIST_CHILD_DIR = "/persist";//persist目录
public static final String CACHE_EXT_NAME_IMAGE = ".image";
public static final String CACHE_EXT_NAME_JSON = ".json";
private static final long THRESHOLD_JSON_SIZE = 1024 * 1024 * 1;// json需要的空间大小1M
private static final long THRESHOLD_IMAGE_SIZE = 1024 * 1024 * 8;// 图片需要的空间大小8M
private static final long CAMERA_SIZE_THRESHOLD = 1024 * 1024 * 16;// 判断摄像头临时存储空间 16M
private static final long PERSIST_FILE_SIZE = 1024 * 1024 * 8;//持久化图片,暂定8M空间
private static final long THRESHOLD_IMAGE_CLEAR_SIZE = 1024 * 1024 * 50;// 存储空间小于50M时,需要清除缓存图片
// 内置存储空间的目录类型
public static final int INTERNAL_TYPE_FILE = 1;
public static final int INTERNAL_TYPE_CACHE = 2;
/**
* @author lijingzuo
*
* Time: 2010-12-31 上午10:37:19
*
* Name:
*
* Description: SDCard正确安装,并且可读写
*
* @return
*
*/
public static boolean isReady() {
return externalMemoryAvailable();
}
public static boolean externalMemoryAvailable() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 获取文件输出流 TODO
*/
public static FileOutputStream openFileOutput(FileGuider fileGuider) throws FileNotFoundException {
long availableSize = fileGuider.getAvailableSize();
if (0 != availableSize) {
if (Directory.INTERNAL == fileGuider.getSpace() && // 内部存储空间不足
getAvailableInternalMemorySize() < availableSize) {
return null;
} else if (Directory.EXTERNAL == fileGuider.getSpace() && // 外部存储空间不足
getAvailableExternalMemorySize() < availableSize) {
return null;
}
}
return MyApplication.getInstance().openFileOutput(fileGuider.getFileName(), fileGuider.getMode());
}
/**
* 获取文件全路径
* @param fileGuider
* @return
*/
public static String getFileAbsolutePath(FileGuider fileGuider) {
return MyApplication.getInstance().getFilesDir().getAbsolutePath() + SYSTEM_OPERATOR + fileGuider.getFileName();
}
/**
* @author lijingzuo
*
* Time: 2010-12-31 上午10:27:03
*
* Name:
*
* Description: 获得 External 应用根目录
*
* @return
*
*/
public static File getExternalDirectory(String childDirName) {
if (Log.D) {
Log.d(TAG, "getExternalDirectory() -->> ");
}
File dir = new File(Environment.getExternalStorageDirectory(), aplcationDir + ((null != childDirName) ? childDirName : ""));
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
/**
* @author lijingzuo
*
* Time: 2010-12-31 上午10:27:03
*
* Name:
*
* Description: 获得 Internal 应用根目录
*
* @return
*
*/
public static File getInternalDirectory(String childDirName, int internalType, boolean isWorldAccess) {
if (Log.D) {
Log.d(TAG, "getInternalDirectory() -->> ");
}
File typeDir = null;
switch (internalType) {
case INTERNAL_TYPE_FILE:
typeDir = MyApplication.getInstance().getFilesDir();
break;
case INTERNAL_TYPE_CACHE:
typeDir = MyApplication.getInstance().getCacheDir();
break;
}
File dir = new File(typeDir, aplcationDir + ((null != childDirName) ? childDirName : ""));
if (!dir.exists()) {
dir.mkdirs();
}
if (isWorldAccess) {// 外部可访问
chModFile(FILE_MODE_WORLD_ACCESS, new File(typeDir, aplcationDir));// /jingdong文件夹外部可访问
chModFile(FILE_MODE_WORLD_ACCESS, dir);// 图片文件夹外部可访问
}
if (Log.D) {
Log.d(TAG, "getInternalDirectory() dir.getAbsolutePath() -->> " + dir.getAbsolutePath());
}
if (Log.D) {
Log.d(TAG, "getInternalDirectory() dir.exists() -->> " + dir.exists());
}
return dir;
}
/**
* @author lijingzuo
*
* Time: 2010-12-31 上午10:27:03
*
* Name:
*
* Description: 获得 Internal 应用根目录(缓存)
*
* @return
*
*/
public static File getInternalDirectory(String childDirName, boolean isWorldAccess) {
return getInternalDirectory(childDirName, INTERNAL_TYPE_CACHE, isWorldAccess);
}
/**
* 选用json所需要存储空间并建立所需子目录
*/
private static Directory getDirectoryByJsonSize(String childDirName) {
if (Log.D) {
Log.d(TAG, "getDirectoryByJsonSize() -->> ");
}
if (getAvailableInternalMemorySize() > THRESHOLD_JSON_SIZE) {// 选用 Internal
// 空间
if (Log.D) {
Log.d(TAG, "getDirectoryByJsonSize() -->> INTERNAL");
}
return new Directory(getInternalDirectory(childDirName, false), Directory.INTERNAL);
} else if (getAvailableExternalMemorySize() > THRESHOLD_JSON_SIZE) {// 选用
// External
// 空间
if (Log.D) {
Log.d(TAG, "getDirectoryByJsonSize() -->> EXTERNAL");
}
return new Directory(getExternalDirectory(childDirName), Directory.EXTERNAL);
}
return null;
}
/**
* 选用image所需要存储空间并建立所需子目录,规则:1.检查有SD卡就用SD卡;2内部存储大于8M用内部存储
*/
private static Directory getDirectoryByImageSize(String childDirName) {
if (Log.D) {
Log.d(TAG, "getDirectoryByImageSize() -->> ");
}
if (externalMemoryAvailable()) { // 选用扩展卡
if (Log.D) {
Log.d(TAG, "getDirectoryByImageSize() -->> EXTERNAL");
}
return new Directory(getExternalDirectory(childDirName), Directory.EXTERNAL);
} else if (getAvailableInternalMemorySize() > THRESHOLD_IMAGE_SIZE) {// 选用 Internal
if (Log.D) {
Log.d(TAG, "getDirectoryByImageSize() -->> INTERNAL");
}
return new Directory(getInternalDirectory(childDirName, false), Directory.INTERNAL);
}
return null;
}
private static Directory getDirectoryByPersistFileSize(String childDirName) {
if (getAvailableInternalMemorySize() > PERSIST_FILE_SIZE) {// 选用 Internal
// 空间
if (Log.D) {
Log.d(TAG, "getDirectoryByJsonSize() -->> INTERNAL");
}
return new Directory(getInternalDirectory(childDirName, false), Directory.INTERNAL);
} else { //没有内部返回空
return null;
}
}
/**
* 尝试获得所需路径
*/
public static Directory getDirectory(int dir) {
switch (dir) {
case JSON_DIR:
return getJsonDirectory();
case IMAGE_DIR:
return getImageDirectory();
case CAMERA_DIR:
return getCameraDirectory();
case PERSIST_DIR:
return getPersistDirectory();
default:
return null;
}
}
/**
* 尝试获得 json 存储路径
*/
private static Directory getJsonDirectory() {
if (Log.D) {
Log.d(TAG, "getJsonDirectory() jsonDirState -->> " + jsonDirState);
}
if (Log.D) {
Log.d(TAG, "getJsonDirectory() jsonDir -->> " + jsonDir);
}
if (!isNeedReSetupStorageStateJson && jsonDirState == -1) {
return null;
} else if (!isNeedReSetupStorageStateJson && null != jsonDir) {
return jsonDir;
}
if (isNeedReSetupStorageStateJson) {
if (Log.D) {
Log.d(TAG, "getJsonDirectory() no preferences -->> ");
}
Directory directory = getDirectoryByJsonSize(JSON_CHILD_DIR);
if (null == directory) {// 没有可用存储空间
if (Log.D) {
Log.d(TAG, "getJsonDirectory() no free size -->> ");
}
jsonDirState = -1;
// 不记录(应用设置),因为希望将来能再次检查
return null;
} else {// 存在存储空间
if (Log.D) {
Log.d(TAG, "getJsonDirectory() has free size -->> ");
}
jsonDir = directory;
jsonDirState = directory.getSpace();
isNeedReSetupStorageStateJson = false;// 此处将标志位改回
return jsonDir;
}
} else {
if (Log.D) {
Log.d(TAG, "getJsonDirectory() is preferences -->> ");
}
if (jsonDirState == 2) {// 外部存储空间
if (!externalMemoryAvailable()) {// 预防外部存储空间意外移除
if (Log.D) {
Log.d(TAG, "getJsonDirectory() no external -->> ");
}
jsonDirState = -1;
return null;
}
}
if (Log.D) {
Log.d(TAG, "getJsonDirectory() jsonFileCachePath -->> " + jsonDir.getDir().getAbsolutePath());
}
jsonDir = new Directory(new File(jsonDir.getDir().getAbsolutePath()), jsonDirState == 1 ? Directory.INTERNAL : Directory.EXTERNAL);
File dir = jsonDir.getDir();
if (!dir.exists()) {// 预防创建之后被意外删除
dir.mkdirs();
}
return jsonDir;
}
}
/**
* 尝试获得 image 存储路径
*/
private static Directory getImageDirectory() {
if (Log.D) {
Log.d(TAG, "getImageDirectory() imageDirState -->> " + imageDirState);
}
if (Log.D) {
Log.d(TAG, "getImageDirectory() imageDir -->> " + imageDir);
}
if (!isNeedReSetupStorageStateImage && imageDirState == -1) {
return null;
} else if (!isNeedReSetupStorageStateImage && null != imageDir) {
return imageDir;
}
if (isNeedReSetupStorageStateImage) {
Directory directory = getDirectoryByImageSize(IMAGE_CHILD_DIR);
if (null == directory) {// 没有可用存储空间
imageDirState = -1;
// 不记录(应用设置),因为希望将来能再次检查
return null;
} else {// 存在存储空间
if (Log.D) {
Log.d(TAG, "getImageDirectory() has free size -->> ");
}
imageDir = directory;
imageDirState = directory.getSpace();
isNeedReSetupStorageStateImage = false;// 此处将标志位改回
return imageDir;
}
} else {
if (imageDirState == 2) {// 外部存储空间
if (!externalMemoryAvailable()) {// 预防外部存储空间意外移除
imageDirState = -1;
return null;
}
}
if (Log.D) {
Log.d(TAG, "getImageDirectory() imageFileCachePath -->> " + imageDir.getDir().getAbsolutePath());
}
imageDir = new Directory(new File(imageDir.getDir().getAbsolutePath()), imageDirState == 1 ? Directory.INTERNAL : Directory.EXTERNAL);
File dir = imageDir.getDir();
if (!dir.exists()) {// 预防创建之后被意外删除
dir.mkdirs();
}
return imageDir;
}
}
/**
* 获取摄像头临时图片存储路径,规则: 1、只存储SD卡中。 3、没有存储返回为null
*
* @return
*/
private static Directory getCameraDirectory() {
if (getTotalExternalMemorySize() > CAMERA_SIZE_THRESHOLD) {// 优先选用外部SD卡
return new Directory(getExternalDirectory(CAMERA_CHILD_DIR), Directory.EXTERNAL);
}
return null;
}
/**
* 获取持久化文件存储路径,该路径下文件不会被清除。内部有控件存在内部,内部没空间放弃存储
* @return
*/
private static Directory getPersistDirectory() {
Directory directory = getDirectoryByPersistFileSize(PERSIST_CHILD_DIR);
return directory;
}
/**
* 保存内容到SDCard
*
* @param filename
* 文件名称
* @param content
* 文件内容
* @throws Exception
*/
public void saveToSDCard(String filename, String content) throws Exception {
saveToSDCard(null, filename, content);
}
/**
* 保存文件
*/
public static boolean saveToSDCard(Directory directory, String fileName, String content) {
return saveToSDCard(directory, fileName, content, Context.MODE_PRIVATE);
}
/**
* 保存文件
*/
public static boolean saveToSDCard(Directory directory, String fileName, String content, int mode) {
if (null == content) {
return false;
}
return saveToSDCard(directory, fileName, content.getBytes(), mode);
}
/**
* 保存文件
*/
public static boolean saveToSDCard(Directory directory, String fileName, byte[] data) {
if (null == data) {
return false;
}
return saveToSDCard(directory, fileName, data, Context.MODE_PRIVATE);
}
/**
* 获取一个文件下有多少个文件
* @param dir
* @return
*/
private static int getSubFilesNum(File dir) {
if (dir != null && dir.exists()) {
String[] names = dir.list();
if (names != null) {
return names.length;
}
}
return UN_KNOW;
}
/**
* 尝试清除片文件夹
* @param directory
*/
private static synchronized void tryCleanImageDir(Directory directory) {
File imageDir = directory.getDir();
int currentNum = 0;
switch (directory.space) {
case Directory.INTERNAL: // 如果从来没有加载过手机内存中的图片数量,那么开始加载手机内存中的图片数量
if (phoneMemoryImageCacheNum == UN_KNOW) {
phoneMemoryImageCacheNum = getSubFilesNum(imageDir);
}
currentNum = phoneMemoryImageCacheNum;
break;
case Directory.EXTERNAL: // 如果从来没有加载过sd卡中的图片数量,那么开始加载sd卡中的图片数量
if (sdCardImageCacheNum == UN_KNOW) {
sdCardImageCacheNum = getSubFilesNum(imageDir);
}
currentNum = sdCardImageCacheNum;
break;
}
if (Log.D) {
Log.d(TAG, "tryCleanImageDir currentNum:" + currentNum);
}
if (currentNum > MAX_IMAGE_SAVE_NUM && deleteOverImageThread == null) {
deleteOverImageThread = new DeleteOverImageThread(imageDir);
deleteOverImageThread.start();
}
}
/**
* 将缓存图片中数量清楚到 最大数量的一半
* @param imageDir2
*/
private static void deleteOverImageWithDir(File imageDir) {
if (imageDir == null || !imageDir.exists()) {
return;
}
File[] files = imageDir.listFiles();
if (files == null) {
return;
}
int length = files.length;
if (length < 1) {
return;
}
Arrays.sort(files, new FileSorter());
int needDeleteNum = length - MAX_IMAGE_SAVE_NUM / 2;
if (Log.D) {
Log.d(TAG, "deleteOverImageWithDir needDeleteNum:" + needDeleteNum);
}
if (needDeleteNum < 0) {
return;
}
File temp;
for (int i = 0; i < needDeleteNum && i <= length; i++) {
temp = files[i];
if (temp != null && temp.exists()) {
if (Log.D) {
Log.d(TAG, "deleteOverImageWithDir temp:" + temp);
}
temp.delete();
}
}
}
/**
* 根据类型保存文件
* @param directory
* @param fileName
* @param content
* @param type
* @return
*/
public static boolean saveToSDCardWithType(Directory directory, String fileName, String content, int type) {
if (TextUtils.isEmpty(content)) {
return false;
}
return saveToSDCardWithType(directory, fileName, content.getBytes(), type);
}
/**
* 根据类型保存文件
* @param directory
* @param fileName
* @param data
* @param type
* @return
*/
public static boolean saveToSDCardWithType(Directory directory, String fileName, byte[] data, int type) {
if (null == data || data.length < 1 || TextUtils.isEmpty(fileName) || directory == null) {
return false;
}
if (Log.D) {
Log.d(TAG, "saveToSDCardWithType phoneMemoryImageCacheNum:" + phoneMemoryImageCacheNum);
Log.d(TAG, "saveToSDCardWithType sdCardImageCacheNum:" + sdCardImageCacheNum);
}
switch (type) {
case IMAGE_DIR: // 图片目录
tryCleanImageDir(directory);
break;
case JSON_DIR: // json目录
break;
}
boolean result = saveToSDCard(directory, fileName, data);
if (Log.D) {
Log.d(TAG, "saveToSDCardWithType result:" + result);
}
if (result && type - IMAGE_DIR == 0) {
incrementImageNum(directory);
}
return result;
}
/**
* 图片计数器增长
* @param directory
*/
private static synchronized void incrementImageNum(Directory directory) {
if (directory == null) {
return;
}
File dir = directory.getDir();
if (dir == null || !dir.exists()) {
return;
}
switch (directory.space) {
case Directory.INTERNAL: // 如果从来没有加载过手机内存中的图片数量,那么开始加载手机内存中的图片数量
if (phoneMemoryImageCacheNum == UN_KNOW) {
phoneMemoryImageCacheNum = getSubFilesNum(dir);
}
phoneMemoryImageCacheNum++;
break;
case Directory.EXTERNAL: // 如果从来没有加载过sd卡中的图片数量,那么开始加载sd卡中的图片数量
if (sdCardImageCacheNum == UN_KNOW) {
sdCardImageCacheNum = getSubFilesNum(dir);
}
sdCardImageCacheNum++;
break;
}
}
/**
* 重置SD卡图片标志位的数量
* @param directory
*/
private static synchronized void resetSdcardImageNum(int resetNum) {
sdCardImageCacheNum = resetNum;
}
/**
* 重置手机存储图片标志位的数量
* @param directory
*/
private static synchronized void resetPhoneMemoryImageNum(int resetNum) {
phoneMemoryImageCacheNum = resetNum;
}
/**
* 保存文件
*/
public static boolean saveToSDCard(Directory directory, String fileName, byte[] data, int mode) {
if (directory == null || TextUtils.isEmpty(fileName) || data == null) {
return false;
}
File dir = directory.getDir();
File file = new File(dir, fileName);
FileOutputStream outStream = null;
// 更新文件的读写权限
if (mode == Context.MODE_WORLD_READABLE) {
chModFile(FILE_MODE_WORLD_READABLE, file);// 图片文件外部可读-rw----r--
} else if (mode == Context.MODE_WORLD_WRITEABLE) {
chModFile(FILE_MODE_WORLD_WRITEABLE, file);// 图片文件外部可写-rw-----w-
}// 否则为默认
try {
outStream = new FileOutputStream(file);
if (null != outStream) {
outStream.write(data);
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (null != outStream) {
try {
outStream.close();
} catch (IOException e) {
}
}
}
return true;
}
/**
* 保存内容
*
* @param filename
* 文件名称
* @param content
* 文件内容
* @throws Exception
*/
public void save(String filename, String content) throws Exception {
FileOutputStream outStream = MyApplication.getInstance().openFileOutput(filename, Context.MODE_PRIVATE);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 以追加方式保存内容
*
* @param filename
* 文件名称
* @param content
* 文件内容
* @throws Exception
*/
public void saveAppend(String filename, String content) throws Exception {// ctrl+shift+y变小写/x变大写
FileOutputStream outStream = MyApplication.getInstance().openFileOutput(filename, Context.MODE_APPEND);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 保存内容,允许其他应用对其进行读访问
*
* @param filename
* 文件名称
* @param content
* 文件内容
* @throws Exception
*/
public void saveReadable(String filename, String content) throws Exception {// ctrl+shift+y变小写/x变大写
FileOutputStream outStream = MyApplication.getInstance().openFileOutput(filename, Context.MODE_WORLD_READABLE);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 保存内容,允许其他应用对其进行写访问
*
* @param filename
* 文件名称
* @param content
* 文件内容
* @throws Exception
*/
public void saveWriteable(String filename, String content) throws Exception {// ctrl+shift+y变小写/x变大写
FileOutputStream outStream = MyApplication.getInstance().openFileOutput(filename, Context.MODE_WORLD_WRITEABLE);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 保存内容,允许其他应用对其进行读写访问
*
* @param filename
* 文件名称
* @param content
* 文件内容
* @throws Exception
*/
public void saveReadableWriteable(String filename, String content) throws Exception {// ctrl+shift+y变小写/x变大写
FileOutputStream outStream = MyApplication.getInstance().openFileOutput(filename, Context.MODE_APPEND + Context.MODE_WORLD_WRITEABLE + Context.MODE_WORLD_READABLE);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 读取内容
*
* @param filename
* 文件名称
* @return 文件内容
* @throws Exception
*/
public String read(String filename) throws Exception {
FileInputStream inStream = MyApplication.getInstance().openFileInput(filename);
byte[] data = readInputStream(inStream);
return new String(data);
}
/**
* 读取内容
*
* @param filename
* 文件名称
* @return 文件内容
* @throws Exception
*/
public byte[] readAsByteArray(String filename) throws Exception {
FileInputStream inStream = MyApplication.getInstance().openFileInput(filename);
return readInputStream(inStream);
}
// 手机:自带存储空间,外部插进来SDCard
public byte[] readInputStream(FileInputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
outStream.close();
return outStream.toByteArray();
}
private static final int ERROR = -1;
/**
* @author lijingzuo
*
* Time: 2011-3-23 下午04:23:09
*
* Name:
*
* Description: 内部可用空间大小
*
* @return
*
*/
static public long getAvailableInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
}
/**
* @author lijingzuo
*
* Time: 2011-3-23 下午04:22:22
*
* Name:
*
* Description: 内部总空间大小
*
* @return
*
*/
static public long getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
long result = totalBlocks * blockSize;
if (Log.D) {
Log.d(TAG, "getTotalInternalMemorySize() -->> " + result);
}
return result;
}
/**
* @author lijingzuo
*
* Time: 2011-3-23 下午04:23:48
*
* Name:
*
* Description: 外部可用空间大小
*
* @return
*
*/
static public long getAvailableExternalMemorySize() {
if (externalMemoryAvailable()) {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
} else {
return ERROR;
}
}
/**
* @author lijingzuo
*
* Time: 2011-3-23 下午04:23:51
*
* Name:
*
* Description: 外部总空间大小
*
* @return
*
*/
static public long getTotalExternalMemorySize() {
if (externalMemoryAvailable()) {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
long result = totalBlocks * blockSize;
if (Log.D) {
Log.d(TAG, "getTotalExternalMemorySize() -->> " + result);
}
return result;
} else {
return ERROR;
}
}
/**
* @author lijingzuo
*
* Time: 2011-3-23 下午04:24:40
*
* Name:
*
* Description: 把空间大小格式化为字符串
*
* @param size
* @return
*
*/
static public String formatSize(long size) {
String suffix = null;
if (size >= 1024) {
suffix = "KiB";
size /= 1024;
if (size >= 1024) {
suffix = "MiB";
size /= 1024;
}
}
StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
int commaOffset = resultBuffer.length() - 3;
while (commaOffset > 0) {
resultBuffer.insert(commaOffset, ',');
commaOffset -= 3;
}
if (suffix != null)
resultBuffer.append(suffix);
return resultBuffer.toString();
}
/**
* @author lijingzuo
*
* Time: 2011-3-23 下午04:24:40
*
* Name:
*
* Description: 把空间大小格式化为字符串(小数点)
*
* @param size
* @return
*
*/
static public String formatSize2(long size) {
String suffix = null;
float sizeF = Long.valueOf(size).floatValue();
if (sizeF >= 1024) {
suffix = "KB";
sizeF = sizeF / 1024;
if (sizeF >= 1024) {
suffix = "MB";
sizeF = sizeF / 1024;
}
}
String format = new DecimalFormat(".00").format(sizeF);
StringBuilder resultBuffer = new StringBuilder(format);
int commaOffset = resultBuffer.indexOf(".") - 3;
while (commaOffset > 0) {
resultBuffer.insert(commaOffset, ',');
commaOffset -= 3;
}
if (suffix != null)
resultBuffer.append(suffix);
return resultBuffer.toString();
}
/**
* 清理缓存文件
*/
public static void clearCacheFiles() {
/*
ArrayList<CacheFile> list = CacheFileTable.getListByClean();
boolean externalMemoryAvailable = FileService.externalMemoryAvailable();
for (int i = 0; i < list.size(); i++) {
CacheFile cacheFile = list.get(i);
if (cacheFile == null) {
continue;
}
Directory directory = cacheFile.getDirectory();
if (directory == null) {
continue;
}
if (directory.getSpace() == Directory.INTERNAL || //
(directory.getSpace() == Directory.EXTERNAL && externalMemoryAvailable == true)) {
boolean result = cacheFile.getFile().delete();
if (Log.D) {
Log.d(TAG, "cacheFile.getName() -->> " + cacheFile.getName());
}
if (result) {
CacheFileTable.delete(cacheFile);
}
}
}
resetPhoneMemoryImageNum(UN_KNOW);
resetSdcardImageNum(UN_KNOW);
*/
}
/**
* 清理手机内部存储的缓存图片: </br>应用退出时,如果当前使用手机内部存储缓存图片,检测手机内部存储如果小于50M,就清除所有存储的图片,释放用户存储空间。
*/
public static void clearInternalCacheImages() {
final Directory imageDir = getImageDirectory();
if (null != imageDir //
&& imageDir.getSpace() == Directory.INTERNAL //
&& getAvailableInternalMemorySize() < THRESHOLD_IMAGE_CLEAR_SIZE) {
deleteAllFilseForDirectory(imageDir);
// 重置手机内存图片中的标志位
resetPhoneMemoryImageNum(UN_KNOW);
}
}
/**
* 清除所有缓存图片,包括SD卡或内部存储的
*/
public static void clearAllCacheImages() {
if (externalMemoryAvailable()) { // 扩展卡可用
//删除扩展卡的缓存图片
final Directory imageDir = new Directory(getExternalDirectory(IMAGE_CHILD_DIR), Directory.EXTERNAL);
deleteAllFilseForDirectory(imageDir);
// 重置sd卡的图片数量标志位
resetSdcardImageNum(UN_KNOW);
}
// 删除内部存储的缓存图片
final Directory imageDir = new Directory(getInternalDirectory(IMAGE_CHILD_DIR, false), Directory.INTERNAL);
deleteAllFilseForDirectory(imageDir);
// 重置手机内存中图片数量的标志位
resetPhoneMemoryImageNum(UN_KNOW);
}
/**
* 删除Directory类指定文件夹下所有文件
* @param directory
*/
private static void deleteAllFilseForDirectory(Directory directory) {
if (directory == null) {
return;
}
File dir = directory.getDir();
if (dir == null || !dir.exists()) {
return;
}
String[] names = dir.list();
if (names == null) {
return;
}
for (String name : names) {
File file = new File(dir, name);
if (file != null && file.exists()) {
file.delete();
}
}
}
/**
* 目录封装类
*/
public static class Directory {
public static final int INTERNAL = 1;
public static final int EXTERNAL = 2;
private File dir;
private String path;
private int space;
public Directory(String path, int space) {
this(new File(path), space);
}
public Directory(File dir, int space) {
this.dir = dir;
this.space = space;
}
public File getDir() {
return dir;
}
public void setDir(File dir) {
this.dir = dir;
}
public int getSpace() {
return space;
}
public void setSpace(int space) {
this.space = space;
}
public String getPath() {
if (null == path && null != dir) {
path = dir.getAbsolutePath();
}
return path;
}
public void setPath(String path) {
if (null == getPath() || !getPath().equals(path)) {
dir = new File(path);
this.path = path;
}
}
}
/**
* 更改指定文件或目录的读、写、执行权限
*
* @param mode
* 需要修改的权限
* @param file
* 文件或文件夹
*/
private static void chModFile(String mode, File file) {
try {
Runtime.getRuntime().exec("chmod " + mode + " " + file);
} catch (Exception e) {
if (Log.D) {
e.printStackTrace();
Log.d(TAG, " -->> chModFile mode:" + mode + " file:" + file + " error:" + e.getMessage());
}
}
}
/**
* 保存共享图片文件,被第三方应用可访问的
* @param imageFile
* @return
*/
public static String saveShareImage(File imageFile) {
String result = null;
FileGuider savePath = new FileGuider();// 统一文件操作对象
savePath.setSpace(Directory.INTERNAL);
savePath.setImmutable(true);
savePath.setFileName(SHARE_IMAGE_NAME);
savePath.setMode(Context.MODE_WORLD_READABLE);
FileOutputStream fileOutputStream = null;// 得到输出流
FileInputStream fileInputStream = null;// 得到输入流
try {
fileOutputStream = FileService.openFileOutput(savePath);
fileInputStream = new FileInputStream(imageFile);
// 复制文件
IOUtil.readAsFile(fileInputStream, fileOutputStream, null, new StopController() {
@Override
public void stop() {
}
@Override
public boolean isStop() {
return false;
}
});
// 得到共享文件名称
result = getFileAbsolutePath(savePath);
} catch (Exception e) {
if (Log.D) {
e.printStackTrace();
Log.d(TAG, " saveShareImage-->> " + e.getMessage());
}
}
return result;
}
/**
* 文件排序机制,按照最后修改时间进行排序(升序,越旧的越在前面)
*/
private static class FileSorter implements Comparator<File> {
@Override
public int compare(File object1, File object2) {
if (object1 == null || object2 == null || object1 == object2) {
return 0;
}
long d1 = object1.lastModified();
long d2 = object2.lastModified();
if (d1 == d2) {
return 0;
} else {
return d1 > d2 ? 1 : -1;
}
}
}
/**
* 后台图片缓存清理线程
* @author tandingqiang
*
*/
private static class DeleteOverImageThread extends Thread {
private File imageDir;
public DeleteOverImageThread(File imageDir) {
super();
this.imageDir = imageDir;
}
@Override
public void run() {
try {
deleteOverImageWithDir(imageDir);
} catch (Throwable e) {
if (Log.D) {
e.printStackTrace();
}
}
resetPhoneMemoryImageNum(UN_KNOW);
resetSdcardImageNum(UN_KNOW);
deleteOverImageThread = null;
}
}
}