/* * Copyright (C) 2012 The Serval Project * * This file is part of the Serval Maps Software * * Serval Maps Software is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This source code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this source code; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.servalproject.maps.utils; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.FileChannel; import java.util.Arrays; import org.servalproject.maps.protobuf.BinaryFileContract; import android.text.TextUtils; import android.util.Log; /** * a class that exposes a number of reusable methods related to files */ public class FileUtils { /** * tests to see if the given path is a directory and can be written to * * @param path the full path to test * @return true if the path is a directory and be be written to */ public static boolean isDirectoryWritable(String path) { if(TextUtils.isEmpty(path) == true) { throw new IllegalArgumentException("the path parameter is required"); } File mPath = new File(path); if(mPath.isDirectory() && mPath.canWrite()) { return true; } else { return mPath.mkdirs(); } } /** * tests to see if the given path is a directory and can be written to * * @param path the full path to test * @return true if the path is a directory and be be written to */ public static boolean isDirectoryReadable(String path) { if(TextUtils.isEmpty(path) == true) { throw new IllegalArgumentException("the path parameter is required"); } File mPath = new File(path); if(mPath.isDirectory() && mPath.canRead()) { return true; } else { return false; } } /** * tests to see if the given path is a file and is readable * * @param path the full path to test * @return true if the path is a file and is readable */ public static boolean isFileReadable(String path) { if(TextUtils.isEmpty(path) == true) { throw new IllegalArgumentException("the path parameter is required"); } File mFile = new File(path); if(mFile.isFile() && mFile.canRead()) { return true; } else { return false; } } /** * copy the contents of one file into another file * @param inputStream an InputStream which is the source of the data * @param destination the destination file * @throws IOException */ public static void copyFile(InputStream inputStream, File destination) throws IOException { try{ OutputStream mOutputStream = new FileOutputStream(destination); try{ byte buff[] = new byte[1024]; int read=0; while((read = inputStream.read(buff)) >=0){ mOutputStream.write(buff, 0, read); } }finally{ mOutputStream.close(); } }finally{ inputStream.close(); } } /** * copies a file into a directory * * @param filePath path to the source file * @param dirPath path to the destination directory * @return the full path of the destination file * @throws IOException */ public static String copyFileToDir(String filePath, String dirPath) throws IOException { File mSourceFile = new File(filePath); File mDestinationFile = new File(dirPath, mSourceFile.getName()); copyFile(new FileInputStream(mSourceFile), mDestinationFile); return mDestinationFile.getAbsolutePath(); } /** * copies a file into a directory * * @param filePath path to the source file * @param dirPath path to the destination directory * @return the full path of the destination file * @throws IOException */ public static String copyFileToDirWithTmpName(String filePath, String dirPath) throws IOException { // check the parameters if(TextUtils.isEmpty(filePath) == true) { throw new IllegalArgumentException("the filePath parameter is required"); } if(TextUtils.isEmpty(dirPath) == true) { throw new IllegalArgumentException("the dirPath paramter is required"); } if(isFileReadable(filePath) == false) { throw new IOException("unable to access the source file"); } if(isDirectoryWritable(dirPath) == false) { throw new IOException("unable to access the destination directory"); } String mFileName = new File(filePath).getName(); File mOutputFile = null; if(mFileName.endsWith(BinaryFileContract.LOCATION_EXT)) { mOutputFile = File.createTempFile(BinaryFileContract.LOCATION_EXT, null, new File(dirPath)); } else { mOutputFile = File.createTempFile(BinaryFileContract.POI_EXT, null, new File(dirPath)); } // copy the file // based on code found at the URL below and considered to be in the public domain // http://stackoverflow.com/questions/1146153/copying-files-from-one-directory-to-another-in-java#answer-1146195 FileChannel mInputChannel = new FileInputStream(filePath).getChannel(); FileChannel mOutputChannel = new FileOutputStream(mOutputFile).getChannel(); mOutputChannel.transferFrom(mInputChannel, 0, mInputChannel.size()); // play nice and tidy up mInputChannel.close(); mOutputChannel.close(); return mOutputFile.getCanonicalPath(); } /** * delete all files in a directory * * @param path the path to the directory * @param extensions a list of extensions to match against * @throws IOException */ public static int deleteFilesInDir(String dirPath, String[] extensions) throws IOException { int count = 0; // check the parameters if(TextUtils.isEmpty(dirPath) == true) { throw new IllegalArgumentException("the dirPath paramter is required"); } if(isDirectoryWritable(dirPath) == false) { throw new IOException("unable to access the required directory: " + dirPath); } // get a list of filee File mDir = new File(dirPath); File[] mFiles = mDir.listFiles(new ExtensionFileFilter(extensions)); for(File mFile: mFiles) { if(mFile.delete()) { count++; } else { throw new IOException("unable to delete file: " + mFile.getCanonicalPath()); } } return count; } /** * delete the specified directory * @param dirPath the full path to the directory * @throws IOException */ public static void deleteDirectory(String dirPath) throws IOException { // check the parameters if(TextUtils.isEmpty(dirPath) == true) { throw new IllegalArgumentException("the dirPath paramter is required"); } if(isDirectoryWritable(dirPath) == false) { throw new IOException("unable to access the required directory: " + dirPath); } if(listFilesInDir(dirPath, null) != null) { Log.d("FileUtils", Arrays.toString(listFilesInDir(dirPath, null))); throw new IOException("unable to delete the directory, it isn't empty"); } // delete the directory File mDirectory = new File(dirPath); if(!mDirectory.delete()) { throw new IOException("unable to delete the specified directory"); } } /** * get a list of files in a directory * * @param dirPath the directory to search for files * @param extensions a list of extensions to filter the list of files, if null all files are returns * @return an array of file names or null if no files match * @throws IOException */ public static String[] listFilesInDir(String dirPath, String[] extensions) throws IOException { String[] mFileList = null; // check the parameters if(TextUtils.isEmpty(dirPath) == true) { throw new IllegalArgumentException("the dirPath paramter is required"); } if(isDirectoryWritable(dirPath) == false) { throw new IOException("unable to access the required directory: " + dirPath); } // get a list of files File mDir = new File(dirPath); File[] mFiles = mDir.listFiles(new ExtensionFileFilter(extensions)); if(mFiles != null && mFiles.length > 0) { mFileList = new String[mFiles.length]; for(int i = 0; i < mFiles.length; i++) { mFileList[i] = mFiles[i].getName(); } Arrays.sort(mFileList); } return mFileList; } // file filter using extensions private static class ExtensionFileFilter implements FileFilter { private String[] extensions; public ExtensionFileFilter(String[] extensions) { this.extensions = extensions; } public boolean accept(File pathname) { if (pathname.isDirectory()) { return false; } if (pathname.canRead() == false) { return false; } String name = pathname.getName().toLowerCase(); if(extensions == null) { if(!name.equals("..") || !name.equals(".")) { return true; } } else { for(String mExtension: extensions) { if(name.endsWith(mExtension)) { return true; } } return false; } return false; } } /** * get the extension component of a file name * * @param fileName the name of the file * @return the extension of the file, or null */ public static String getExtension(String fileName) { if(fileName == null) { return null; } int mLocation = fileName.lastIndexOf("."); if(mLocation == -1) { return null; } else { return fileName.substring(mLocation + 1); } } }