project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java
changeset 10017 de822cd3df3a
parent 7586 33924ff4af50
equal deleted inserted replaced
10015:4feced261c68 10017:de822cd3df3a
    38 import android.os.Build;
    38 import android.os.Build;
    39 import android.os.Environment;
    39 import android.os.Environment;
    40 import android.util.Log;
    40 import android.util.Log;
    41 
    41 
    42 public class FileUtils {
    42 public class FileUtils {
    43 	private static final String ROOT_DIR = "Data";
    43     private static final String ROOT_DIR = "Data";
    44 	private static final String TAG = FileUtils.class.getSimpleName();
    44     private static final String TAG = FileUtils.class.getSimpleName();
    45 
    45 
    46 	/**
    46     /**
    47 	 * @return true if the data path is currently available. However, it can vanish at any time so
    47      * @return true if the data path is currently available. However, it can vanish at any time so
    48 	 * normally you should just try to use it and rely on the exceptions.
    48      * normally you should just try to use it and rely on the exceptions.
    49 	 */
    49      */
    50 	public static boolean isDataPathAvailable() {
    50     public static boolean isDataPathAvailable() {
    51 		return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    51         return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    52 	}
    52     }
    53 	
    53 
    54 	/**
    54     /**
    55 	 * get the path to which we should download all the data files
    55      * get the path to which we should download all the data files
    56 	 * @param c context 
    56      * @param c context
    57 	 * @return The directory
    57      * @return The directory
    58 	 * @throws FileNotFoundException if external storage is not available at the moment
    58      * @throws FileNotFoundException if external storage is not available at the moment
    59 	 */
    59      */
    60 	public static File getCachePath(Context c) throws FileNotFoundException {
    60     public static File getCachePath(Context c) throws FileNotFoundException {
    61 		File cachePath = null;
    61         File cachePath = null;
    62 		if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO
    62         if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO
    63 			cachePath = PreFroyoSDCardDir.getDownloadPath(c);
    63             cachePath = PreFroyoSDCardDir.getDownloadPath(c);
    64 		} else {
    64         } else {
    65 			cachePath = FroyoSDCardDir.getDownloadPath(c);
    65             cachePath = FroyoSDCardDir.getDownloadPath(c);
    66 		}
    66         }
    67 		if(cachePath==null) {
    67         if(cachePath==null) {
    68 			throw new FileNotFoundException("External storage is currently unavailable");
    68             throw new FileNotFoundException("External storage is currently unavailable");
    69 		} else {
    69         } else {
    70 			return cachePath;
    70             return cachePath;
    71 		}
    71         }
    72 	}
    72     }
    73 
    73 
    74 	public static File getDataPathFile(Context c, String...subpath) throws FileNotFoundException {
    74     public static File getDataPathFile(Context c, String...subpath) throws FileNotFoundException {
    75 		File file = new File(getCachePath(c), ROOT_DIR);
    75         File file = new File(getCachePath(c), ROOT_DIR);
    76 		for(String pathcomponent : subpath) {
    76         for(String pathcomponent : subpath) {
    77 			file = new File(file, pathcomponent);
    77             file = new File(file, pathcomponent);
    78 		}
    78         }
    79 		return file;
    79         return file;
    80 	}
    80     }
    81 	
    81 
    82 	@TargetApi(8)
    82     @TargetApi(8)
    83 	private static class FroyoSDCardDir{
    83     private static class FroyoSDCardDir{
    84 		public static File getDownloadPath(Context c){
    84         public static File getDownloadPath(Context c){
    85 			return c.getExternalCacheDir();
    85             return c.getExternalCacheDir();
    86 		}
    86         }
    87 	}
    87     }
    88 
    88 
    89 	private static class PreFroyoSDCardDir{
    89     private static class PreFroyoSDCardDir{
    90 		public static File getDownloadPath(Context c){
    90         public static File getDownloadPath(Context c){
    91 			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    91             if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    92 				File extStorageDir = Environment.getExternalStorageDirectory();
    92                 File extStorageDir = Environment.getExternalStorageDirectory();
    93 				if(extStorageDir != null) {
    93                 if(extStorageDir != null) {
    94 					return new File(extStorageDir, "Hedgewars");
    94                     return new File(extStorageDir, "Hedgewars");
    95 				}
    95                 }
    96 			}
    96             }
    97 			return null;
    97             return null;
    98 		}
    98         }
    99 	}
    99     }
   100 
   100 
   101 	/**
   101     /**
   102 	 * Return a File array with all the files from dirName
   102      * Return a File array with all the files from dirName
   103 	 * @param c
   103      * @param c
   104 	 * @param dirName
   104      * @param dirName
   105 	 * @return
   105      * @return
   106 	 * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dirName" does not exist
   106      * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dirName" does not exist
   107 	 */
   107      */
   108 	public static File[] getFilesFromRelativeDir(Context c, String dirName) throws FileNotFoundException {
   108     public static File[] getFilesFromRelativeDir(Context c, String dirName) throws FileNotFoundException {
   109 		File f = getDataPathFile(c, dirName);
   109         File f = getDataPathFile(c, dirName);
   110 
   110 
   111 		if(f.isDirectory()) {
   111         if(f.isDirectory()) {
   112 			return f.listFiles();
   112             return f.listFiles();
   113 		} else {
   113         } else {
   114 			throw new FileNotFoundException("Directory "+dirName+" does not exist.");
   114             throw new FileNotFoundException("Directory "+dirName+" does not exist.");
   115 		}
   115         }
   116 	}
   116     }
   117 
   117 
   118 	/**
   118     /**
   119 	 * Checks if this directory has a file with suffix suffix
   119      * Checks if this directory has a file with suffix suffix
   120 	 * @param f - directory
   120      * @param f - directory
   121 	 * @return
   121      * @return
   122 	 */
   122      */
   123 	public static boolean hasFileWithSuffix(File f, String suffix){
   123     public static boolean hasFileWithSuffix(File f, String suffix){
   124 		if(f.isDirectory()){
   124         if(f.isDirectory()){
   125 			for(String s : f.list()){
   125             for(String s : f.list()){
   126 				if(s.endsWith(suffix)) return true;
   126                 if(s.endsWith(suffix)) return true;
   127 			}
   127             }
   128 			return false;
   128             return false;
   129 		}else{
   129         }else{
   130 			return false;
   130             return false;
   131 		}
   131         }
   132 	}
   132     }
   133 
   133 
   134 	/**
   134     /**
   135 	 * Gives back all dirs which contain a file with suffix fileSuffix
   135      * Gives back all dirs which contain a file with suffix fileSuffix
   136 	 * @param c
   136      * @param c
   137 	 * @param path
   137      * @param path
   138 	 * @param fileSuffix
   138      * @param fileSuffix
   139 	 * @return
   139      * @return
   140 	 * @throws FileNotFoundException If the sdcard is not available or the subdirectory "path" does not exist
   140      * @throws FileNotFoundException If the sdcard is not available or the subdirectory "path" does not exist
   141 	 */
   141      */
   142 	public static List<String> getDirsWithFileSuffix(Context c, String path, String fileSuffix) throws FileNotFoundException{
   142     public static List<String> getDirsWithFileSuffix(Context c, String path, String fileSuffix) throws FileNotFoundException{
   143 		File[] files = getFilesFromRelativeDir(c,path);
   143         File[] files = getFilesFromRelativeDir(c,path);
   144 		ArrayList<String> ret = new ArrayList<String>();
   144         ArrayList<String> ret = new ArrayList<String>();
   145 
   145 
   146 		for(File f : files){
   146         for(File f : files){
   147 			if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName());
   147             if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName());
   148 		}
   148         }
   149 		return ret;
   149         return ret;
   150 	}
   150     }
   151 
   151 
   152 	/**
   152     /**
   153 	 * Get all files from directory dir which have the given suffix
   153      * Get all files from directory dir which have the given suffix
   154 	 * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dir" does not exist
   154      * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dir" does not exist
   155 	 */
   155      */
   156 	public static List<String> getFileNamesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix) throws FileNotFoundException{
   156     public static List<String> getFileNamesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix) throws FileNotFoundException{
   157 		File[] files = FileUtils.getFilesFromRelativeDir(c, dir);
   157         File[] files = FileUtils.getFilesFromRelativeDir(c, dir);
   158 		List<String> ret = new ArrayList<String>();
   158         List<String> ret = new ArrayList<String>();
   159 		for(File file : files){
   159         for(File file : files){
   160 			String s = file.getName();
   160             String s = file.getName();
   161 			if(s.endsWith(suffix)){
   161             if(s.endsWith(suffix)){
   162 				if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length()));
   162                 if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length()));
   163 				else ret.add(s);
   163                 else ret.add(s);
   164 			}
   164             }
   165 		}
   165         }
   166 		return ret;
   166         return ret;
   167 	}
   167     }
   168 
   168 
   169 	/**
   169     /**
   170 	 * Close a resource (possibly null), ignoring any IOException.
   170      * Close a resource (possibly null), ignoring any IOException.
   171 	 */
   171      */
   172 	public static void closeQuietly(Closeable c) {
   172     public static void closeQuietly(Closeable c) {
   173 		if(c!=null) {
   173         if(c!=null) {
   174 			try {
   174             try {
   175 				c.close();
   175                 c.close();
   176 			} catch(IOException e) {
   176             } catch(IOException e) {
   177 				Log.w(TAG, e);
   177                 Log.w(TAG, e);
   178 			}
   178             }
   179 		}
   179         }
   180 	}
   180     }
   181 	
   181 
   182 	/**
   182     /**
   183 	 * Write all data from the input stream to the file, creating or overwriting it.
   183      * Write all data from the input stream to the file, creating or overwriting it.
   184 	 * The input stream will be closed.
   184      * The input stream will be closed.
   185 	 * 
   185      *
   186 	 * @throws IOException
   186      * @throws IOException
   187 	 */
   187      */
   188 	public static void writeStreamToFile(InputStream is, File file) throws IOException {
   188     public static void writeStreamToFile(InputStream is, File file) throws IOException {
   189 		OutputStream os = null;
   189         OutputStream os = null;
   190 		byte[] buffer = new byte[8192];
   190         byte[] buffer = new byte[8192];
   191 		try {
   191         try {
   192 			os = new FileOutputStream(file);
   192             os = new FileOutputStream(file);
   193 			int size;
   193             int size;
   194 			while((size=is.read(buffer)) != -1) {
   194             while((size=is.read(buffer)) != -1) {
   195 				os.write(buffer, 0, size);
   195                 os.write(buffer, 0, size);
   196 			}
   196             }
   197 			os.close(); // Important to close this non-quietly, in case of exceptions when flushing
   197             os.close(); // Important to close this non-quietly, in case of exceptions when flushing
   198 		} finally {
   198         } finally {
   199 			FileUtils.closeQuietly(is);
   199             FileUtils.closeQuietly(is);
   200 			FileUtils.closeQuietly(os);
   200             FileUtils.closeQuietly(os);
   201 		}
   201         }
   202 	}
   202     }
   203 	
   203 
   204 	/**
   204     /**
   205 	 * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory
   205      * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory
   206 	 * @param c
   206      * @param c
   207 	 * @param sourceResId
   207      * @param sourceResId
   208 	 * @param directory
   208      * @param directory
   209 	 */
   209      */
   210 	public static void resRawToFilesDir(Context c, int sourceResId, int targetFilenames, String directory) throws IOException {
   210     public static void resRawToFilesDir(Context c, int sourceResId, int targetFilenames, String directory) throws IOException {
   211 		File targetDir = new File(c.getFilesDir(), directory);
   211         File targetDir = new File(c.getFilesDir(), directory);
   212 		targetDir.mkdirs();
   212         targetDir.mkdirs();
   213 
   213 
   214 		//Get an array with the resource files ID
   214         //Get an array with the resource files ID
   215 		Resources resources = c.getResources();
   215         Resources resources = c.getResources();
   216 		TypedArray ta = resources.obtainTypedArray(sourceResId);
   216         TypedArray ta = resources.obtainTypedArray(sourceResId);
   217 		TypedArray filenames = resources.obtainTypedArray(targetFilenames);
   217         TypedArray filenames = resources.obtainTypedArray(targetFilenames);
   218 		for(int i = 0; i < ta.length(); i++){
   218         for(int i = 0; i < ta.length(); i++){
   219 			int resId =  ta.getResourceId(i, 0);
   219             int resId =  ta.getResourceId(i, 0);
   220 			String fileName = filenames.getString(i);
   220             String fileName = filenames.getString(i);
   221 			File f = new File(targetDir, fileName);
   221             File f = new File(targetDir, fileName);
   222 			writeStreamToFile(resources.openRawResource(resId), f);
   222             writeStreamToFile(resources.openRawResource(resId), f);
   223 		}
   223         }
   224 	}
   224     }
   225 
   225 
   226 	public static String readToString(InputStream is) throws IOException {
   226     public static String readToString(InputStream is) throws IOException {
   227 		try {
   227         try {
   228 			ByteArrayOutputStream os = new ByteArrayOutputStream();
   228             ByteArrayOutputStream os = new ByteArrayOutputStream();
   229 			byte[] buffer = new byte[8192];
   229             byte[] buffer = new byte[8192];
   230 			int size;
   230             int size;
   231 			while((size=is.read(buffer)) != -1) {
   231             while((size=is.read(buffer)) != -1) {
   232 				os.write(buffer, 0, size);
   232                 os.write(buffer, 0, size);
   233 			}
   233             }
   234 			return new String(os.toByteArray());
   234             return new String(os.toByteArray());
   235 		} finally {
   235         } finally {
   236 			closeQuietly(is);
   236             closeQuietly(is);
   237 		}
   237         }
   238 	}
   238     }
   239 	
   239 
   240 	private static final char[] badFilenameChars = new char[] { '/', '\\', ':', '*', '?', '\"', '<', '>', '|', '.', '\0' };
   240     private static final char[] badFilenameChars = new char[] { '/', '\\', ':', '*', '?', '\"', '<', '>', '|', '.', '\0' };
   241 	
   241 
   242 	/**
   242     /**
   243 	 * Modify the given String so that it can be used as part of a filename
   243      * Modify the given String so that it can be used as part of a filename
   244 	 * without causing problems from illegal/special characters.
   244      * without causing problems from illegal/special characters.
   245 	 * 
   245      *
   246 	 * The result should be similar to the input, but isn't necessarily
   246      * The result should be similar to the input, but isn't necessarily
   247 	 * reversible.
   247      * reversible.
   248 	 */
   248      */
   249 	public static String replaceBadChars(String name) {
   249     public static String replaceBadChars(String name) {
   250 		if (name == null || name.trim().length()==0) {
   250         if (name == null || name.trim().length()==0) {
   251 			return "_";
   251             return "_";
   252 		}
   252         }
   253 		name = name.trim();
   253         name = name.trim();
   254 		for (char badChar : badFilenameChars) {
   254         for (char badChar : badFilenameChars) {
   255 			name = name.replace(badChar, '_');
   255             name = name.replace(badChar, '_');
   256 		}
   256         }
   257 		return name;
   257         return name;
   258 	}
   258     }
   259 }
   259 }