summaryrefslogtreecommitdiff
path: root/base/android/java/src/org/chromium/base/FileUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'base/android/java/src/org/chromium/base/FileUtils.java')
-rw-r--r--base/android/java/src/org/chromium/base/FileUtils.java149
1 files changed, 149 insertions, 0 deletions
diff --git a/base/android/java/src/org/chromium/base/FileUtils.java b/base/android/java/src/org/chromium/base/FileUtils.java
new file mode 100644
index 0000000000..e44cd928ae
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/FileUtils.java
@@ -0,0 +1,149 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base;
+
+import android.content.Context;
+import android.net.Uri;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Helper methods for dealing with Files.
+ */
+public class FileUtils {
+ private static final String TAG = "FileUtils";
+
+ /**
+ * Delete the given File and (if it's a directory) everything within it.
+ */
+ public static void recursivelyDeleteFile(File currentFile) {
+ ThreadUtils.assertOnBackgroundThread();
+ if (currentFile.isDirectory()) {
+ File[] files = currentFile.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ recursivelyDeleteFile(file);
+ }
+ }
+ }
+
+ if (!currentFile.delete()) Log.e(TAG, "Failed to delete: " + currentFile);
+ }
+
+ /**
+ * Delete the given files or directories by calling {@link #recursivelyDeleteFile(File)}.
+ * @param files The files to delete.
+ */
+ public static void batchDeleteFiles(List<File> files) {
+ ThreadUtils.assertOnBackgroundThread();
+
+ for (File file : files) {
+ if (file.exists()) recursivelyDeleteFile(file);
+ }
+ }
+
+ /**
+ * Extracts an asset from the app's APK to a file.
+ * @param context
+ * @param assetName Name of the asset to extract.
+ * @param dest File to extract the asset to.
+ * @return true on success.
+ */
+ public static boolean extractAsset(Context context, String assetName, File dest) {
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ try {
+ inputStream = context.getAssets().open(assetName);
+ outputStream = new BufferedOutputStream(new FileOutputStream(dest));
+ byte[] buffer = new byte[8192];
+ int c;
+ while ((c = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, c);
+ }
+ inputStream.close();
+ outputStream.close();
+ return true;
+ } catch (IOException e) {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException ex) {
+ }
+ }
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ } catch (IOException ex) {
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Atomically copies the data from an input stream into an output file.
+ * @param is Input file stream to read data from.
+ * @param outFile Output file path.
+ * @param buffer Caller-provided buffer. Provided to avoid allocating the same
+ * buffer on each call when copying several files in sequence.
+ * @throws IOException in case of I/O error.
+ */
+ public static void copyFileStreamAtomicWithBuffer(InputStream is, File outFile, byte[] buffer)
+ throws IOException {
+ File tmpOutputFile = new File(outFile.getPath() + ".tmp");
+ try (OutputStream os = new FileOutputStream(tmpOutputFile)) {
+ Log.i(TAG, "Writing to %s", outFile);
+
+ int count = 0;
+ while ((count = is.read(buffer, 0, buffer.length)) != -1) {
+ os.write(buffer, 0, count);
+ }
+ }
+ if (!tmpOutputFile.renameTo(outFile)) {
+ throw new IOException();
+ }
+ }
+
+ /**
+ * Returns a URI that points at the file.
+ * @param file File to get a URI for.
+ * @return URI that points at that file, either as a content:// URI or a file:// URI.
+ */
+ public static Uri getUriForFile(File file) {
+ // TODO(crbug/709584): Uncomment this when http://crbug.com/709584 has been fixed.
+ // assert !ThreadUtils.runningOnUiThread();
+ Uri uri = null;
+
+ try {
+ // Try to obtain a content:// URI, which is preferred to a file:// URI so that
+ // receiving apps don't attempt to determine the file's mime type (which often fails).
+ uri = ContentUriUtils.getContentUriFromFile(file);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Could not create content uri: " + e);
+ }
+
+ if (uri == null) uri = Uri.fromFile(file);
+
+ return uri;
+ }
+
+ /**
+ * Returns the file extension, or an empty string if none.
+ * @param file Name of the file, with or without the full path.
+ * @return empty string if no extension, extension otherwise.
+ */
+ public static String getExtension(String file) {
+ int index = file.lastIndexOf('.');
+ if (index == -1) return "";
+ return file.substring(index + 1).toLowerCase(Locale.US);
+ }
+}