AI2 Component  (Version nb184)
FileUtil.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2009-2011 Google, All Rights reserved
3 // Copyright 2011-2020 MIT, All rights reserved
4 // Released under the Apache License, Version 2.0
5 // http://www.apache.org/licenses/LICENSE-2.0
6 
7 package com.google.appinventor.components.runtime.util;
8 
9 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
10 
11 import android.Manifest;
12 import android.os.Environment;
13 import android.util.Log;
14 
18 
19 import java.io.BufferedInputStream;
20 import java.io.BufferedOutputStream;
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.net.URI;
30 import java.net.URL;
31 
37 public class FileUtil {
38  private static final String LOG_TAG = FileUtil.class.getSimpleName();
39  // Note: Some phones come with a "Documents" directory rather than a
40  // "My Documents" directory. Should we check for this and try to be
41  // consistent with the phone's directory structure or to be consistent
42  // in directory names across phones?
43  private static final String DOCUMENT_DIRECTORY = "My Documents/";
44 
45  private static final String DIRECTORY_RECORDINGS = "Recordings";
46 
47  private static final String FILENAME_PREFIX = "app_inventor_";
48 
49  // This has the same value as Environment.DIRECTORY_PICTURES, which was
50  // not defined until API Level 8 (Android 2.2).
51  // If we use Environment.DIRECTORY_PICTURES here, then this class (FileUtil)
52  // will be rejected by the dalvikvm class verifier on older versions of
53  // Android.
54  private static final String DIRECTORY_PICTURES = "Pictures";
55 
56  private static final String DIRECTORY_DOWNLOADS = "Downloads";
57 
58  private FileUtil() {
59  }
60 
64  public static String getFileUrl(String localFileName) {
65  File file = new File(localFileName);
66  return file.toURI().toString();
67  }
68 
78  @Deprecated
79  public static byte[] readFile(String inputFileName) throws IOException {
80  Log.w(LOG_TAG, "Calling deprecated function readFile", new IllegalAccessException());
81  return readFile(Form.getActiveForm(), inputFileName);
82  }
83 
91  public static byte[] readFile(Form form, String inputFileName) throws IOException {
92  File inputFile = new File(inputFileName);
93  // There are cases where our caller will hand us a file to read that
94  // doesn't exist and is expecting a FileNotFoundException if this is the
95  // case. So we check if the file exists and throw the exception
96  if (!inputFile.isFile()) {
97  throw new FileNotFoundException("Cannot find file: " + inputFileName);
98  }
99  FileInputStream inputStream = null;
100  byte[] content;
101  try {
102  inputStream = openFile(form, inputFileName);
103  int fileLength = (int) inputFile.length();
104  content = new byte[fileLength];
105  int offset = 0;
106  int bytesRead;
107  do {
108  bytesRead = inputStream.read(content, offset, fileLength - offset);
109  if (bytesRead > 0) {
110  offset += bytesRead;
111  }
112  if (offset == fileLength) {
113  break;
114  }
115  } while (bytesRead >= 0);
116  } finally {
117  if (inputStream != null) {
118  inputStream.close();
119  }
120  }
121  return content;
122  }
123 
143  @Deprecated
144  public static FileInputStream openFile(String fileName) throws IOException, PermissionException {
145  Log.w(LOG_TAG, "Calling deprecated function openFile", new IllegalAccessException());
146  return openFile(Form.getActiveForm(), fileName);
147  }
148 
165  public static FileInputStream openFile(Form form, String fileName) throws IOException,
167  if (MediaUtil.isExternalFile(form, fileName)) {
168  form.assertPermission(READ_EXTERNAL_STORAGE);
169  }
170  return new FileInputStream(fileName);
171  }
172 
192  @Deprecated
193  public static FileInputStream openFile(File file) throws IOException, PermissionException {
194  Log.w(LOG_TAG, "Calling deprecated function openFile", new IllegalAccessException());
195  return openFile(Form.getActiveForm(), file.getAbsolutePath());
196  }
197 
214  public static FileInputStream openFile(Form form, File file) throws IOException,
216  return openFile(form, file.getAbsolutePath());
217  }
218 
238  @Deprecated
239  public static FileInputStream openFile(URI fileUri) throws IOException, PermissionException {
240  Log.w(LOG_TAG, "Calling deprecated function openFile", new IllegalAccessException());
241  return openFile(Form.getActiveForm(), fileUri);
242  }
243 
260  public static FileInputStream openFile(Form form, URI fileUri) throws IOException,
262  if (MediaUtil.isExternalFileUrl(form, fileUri.toString())) {
263  form.assertPermission(READ_EXTERNAL_STORAGE);
264  }
265  return new FileInputStream(new File(fileUri));
266  }
267 
275  public static String downloadUrlToFile(String url, String outputFileName) throws IOException {
276  InputStream in = new URL(url).openStream();
277  try {
278  return writeStreamToFile(in, outputFileName);
279  } finally {
280  in.close();
281  }
282  }
283 
291  public static String writeFile(byte[] array, String outputFileName) throws IOException {
292  InputStream in = new ByteArrayInputStream(array);
293  try {
294  return writeStreamToFile(in, outputFileName);
295  } finally {
296  in.close();
297  }
298  }
299 
307  public static String copyFile(String inputFileName, String outputFileName)
308  throws IOException {
309  InputStream in = new FileInputStream(inputFileName);
310  try {
311  return writeStreamToFile(in, outputFileName);
312  } finally {
313  in.close();
314  }
315  }
316 
324  public static String writeStreamToFile(InputStream in, String outputFileName) throws IOException {
325  File file = new File(outputFileName);
326 
327  // Create the parent directory.
328  file.getParentFile().mkdirs();
329 
330  OutputStream out = new FileOutputStream(file);
331  try {
332  copy(in, out);
333 
334  // Return the URL to the output file.
335  return file.toURI().toString();
336  } finally {
337  out.flush();
338  out.close();
339  }
340  }
341 
342  private static void copy(InputStream in, OutputStream out) throws IOException {
343  out = new BufferedOutputStream(out, 0x1000);
344  in = new BufferedInputStream(in, 0x1000);
345 
346  // Copy the contents from the input stream to the output stream.
347  while (true) {
348  int b = in.read();
349  if (b == -1) {
350  break;
351  }
352  out.write(b);
353  }
354  out.flush();
355  }
356 
374  @Deprecated
375  public static File getPictureFile(String extension)
376  throws IOException, FileException {
377  Log.w(LOG_TAG, "Calling deprecated function getPictureFile", new IllegalAccessException());
378  return getPictureFile(Form.getActiveForm(), extension);
379  }
380 
394  public static File getPictureFile(Form form, String extension)
395  throws IOException, FileException {
396  return getFile(form, DIRECTORY_PICTURES, extension);
397  }
398 
416  @Deprecated
417  public static File getRecordingFile(String extension)
418  throws IOException, FileException {
419  return getRecordingFile(Form.getActiveForm(), extension);
420  }
421 
435  public static File getRecordingFile(Form form, String extension)
436  throws IOException, FileException {
437  return getFile(form, DIRECTORY_RECORDINGS, extension);
438  }
439 
457  @Deprecated
458  public static File getDownloadFile(String extension)
459  throws IOException, FileException {
460  Log.w(LOG_TAG, "Calling deprecated function getDownloadFile", new IllegalAccessException());
461  return getDownloadFile(Form.getActiveForm(), extension);
462  }
463 
477  public static File getDownloadFile(Form form, String extension)
478  throws IOException, FileException {
479  return getFile(form, DIRECTORY_DOWNLOADS, extension);
480  }
481 
493  private static File getFile(Form form, String category, String extension)
494  throws IOException, FileException {
495  String fileName = DOCUMENT_DIRECTORY + category + "/" + FILENAME_PREFIX
496  + System.currentTimeMillis() + "." + extension;
497  return getExternalFile(form, fileName);
498  }
499 
518  @Deprecated
519  public static File getExternalFile(String fileName) throws IOException, FileException,
520  SecurityException {
521  return getExternalFile(Form.getActiveForm(), fileName);
522  }
523 
538  public static File getExternalFile(Form form, String fileName)
539  throws IOException, FileException, SecurityException {
541  File file = new File(QUtil.getExternalStoragePath(form), fileName);
542  File directory = file.getParentFile();
543  if (form != null) {
544  form.assertPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
545  }
546  if (!directory.exists() && !directory.mkdirs()) {
547  throw new IOException("Unable to create directory " + directory.getAbsolutePath());
548  }
549  if (file.exists()) {
550  if (!file.delete()) {
551  throw new IOException("Cannot overwrite existing file " + file.getAbsolutePath());
552  }
553  }
554  return file;
555  }
556 
557  /*
558  * Checks that external storage is mounted writeable. If it isn't,
559  * throws an exception.
560  */
561  public static void checkExternalStorageWriteable() throws FileException {
562  String state = Environment.getExternalStorageState();
563  if (Environment.MEDIA_MOUNTED.equals(state)) {
564  return;
565  }
566  if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
567  throw new FileException(ErrorMessages.ERROR_MEDIA_EXTERNAL_STORAGE_READONLY);
568  } else {
570  }
571  }
572 
578  public static class FileException extends RuntimeError {
579  private final int msgNumber;
580  public FileException(int errorMsgNumber) {
581  msgNumber = errorMsgNumber;
582  }
583 
584  public int getErrorMessageNumber() {
585  return msgNumber;
586  }
587  }
588 }
com.google.appinventor.components.runtime.util.FileUtil.openFile
static FileInputStream openFile(Form form, String fileName)
Definition: FileUtil.java:165
com.google.appinventor.components.runtime.util.MediaUtil.isExternalFile
static boolean isExternalFile(String mediaPath)
Definition: MediaUtil.java:218
com.google.appinventor.components.runtime.util.QUtil.getExternalStoragePath
static String getExternalStoragePath(Context context, boolean forcePrivate)
Definition: QUtil.java:36
com.google.appinventor.components.runtime.util.ErrorMessages
Definition: ErrorMessages.java:17
com.google.appinventor.components.runtime.util.ErrorMessages.ERROR_MEDIA_EXTERNAL_STORAGE_NOT_AVAILABLE
static final int ERROR_MEDIA_EXTERNAL_STORAGE_NOT_AVAILABLE
Definition: ErrorMessages.java:97
com.google.appinventor.components.runtime.util.FileUtil
Definition: FileUtil.java:37
com.google.appinventor.components.runtime.util.FileUtil.writeFile
static String writeFile(byte[] array, String outputFileName)
Definition: FileUtil.java:291
com.google.appinventor.components.runtime.util.FileUtil.getRecordingFile
static File getRecordingFile(String extension)
Definition: FileUtil.java:417
com.google.appinventor.components
com.google.appinventor.components.runtime.util.FileUtil.getDownloadFile
static File getDownloadFile(Form form, String extension)
Definition: FileUtil.java:477
com.google.appinventor.components.runtime.util.FileUtil.getFileUrl
static String getFileUrl(String localFileName)
Definition: FileUtil.java:64
com.google.appinventor.components.runtime.util.FileUtil.checkExternalStorageWriteable
static void checkExternalStorageWriteable()
Definition: FileUtil.java:561
com.google.appinventor.components.runtime.util.FileUtil.getDownloadFile
static File getDownloadFile(String extension)
Definition: FileUtil.java:458
com.google.appinventor.components.runtime.util.MediaUtil
Definition: MediaUtil.java:53
com.google.appinventor.components.runtime.util.FileUtil.openFile
static FileInputStream openFile(URI fileUri)
Definition: FileUtil.java:239
com.google.appinventor.components.runtime.util.FileUtil.readFile
static byte[] readFile(String inputFileName)
Definition: FileUtil.java:79
com.google.appinventor.components.runtime.util.FileUtil.getPictureFile
static File getPictureFile(String extension)
Definition: FileUtil.java:375
com.google.appinventor.components.runtime.util.QUtil
Definition: QUtil.java:18
com.google.appinventor.components.runtime.util.MediaUtil.isExternalFileUrl
static boolean isExternalFileUrl(String mediaPath)
Definition: MediaUtil.java:182
com.google.appinventor.components.runtime.util.FileUtil.getPictureFile
static File getPictureFile(Form form, String extension)
Definition: FileUtil.java:394
com.google.appinventor.components.runtime.util.FileUtil.downloadUrlToFile
static String downloadUrlToFile(String url, String outputFileName)
Definition: FileUtil.java:275
com.google.appinventor.components.runtime.util.FileUtil.writeStreamToFile
static String writeStreamToFile(InputStream in, String outputFileName)
Definition: FileUtil.java:324
com.google.appinventor.components.runtime.errors.PermissionException
Definition: PermissionException.java:16
com.google.appinventor.components.runtime
Copyright 2009-2011 Google, All Rights reserved.
Definition: AccelerometerSensor.java:8
com.google.appinventor.components.runtime.util.FileUtil.openFile
static FileInputStream openFile(Form form, File file)
Definition: FileUtil.java:214
com.google.appinventor.components.runtime.util.FileUtil.getRecordingFile
static File getRecordingFile(Form form, String extension)
Definition: FileUtil.java:435
com.google.appinventor.components.runtime.util.FileUtil.getExternalFile
static File getExternalFile(Form form, String fileName)
Definition: FileUtil.java:538
com.google.appinventor.components.runtime.util.FileUtil.openFile
static FileInputStream openFile(File file)
Definition: FileUtil.java:193
com.google
com
com.google.appinventor.components.runtime.util.FileUtil.openFile
static FileInputStream openFile(Form form, URI fileUri)
Definition: FileUtil.java:260
com.google.appinventor.components.runtime.util.FileUtil.openFile
static FileInputStream openFile(String fileName)
Definition: FileUtil.java:144
com.google.appinventor.components.runtime.errors
Definition: ArrayIndexOutOfBoundsError.java:7
com.google.appinventor.components.runtime.util.FileUtil.readFile
static byte[] readFile(Form form, String inputFileName)
Definition: FileUtil.java:91
com.google.appinventor.components.runtime.util.ErrorMessages.ERROR_MEDIA_EXTERNAL_STORAGE_READONLY
static final int ERROR_MEDIA_EXTERNAL_STORAGE_READONLY
Definition: ErrorMessages.java:96
com.google.appinventor.components.runtime.Form.getActiveForm
static Form getActiveForm()
Definition: Form.java:2181
com.google.appinventor.components.runtime.util.FileUtil.copyFile
static String copyFile(String inputFileName, String outputFileName)
Definition: FileUtil.java:307
com.google.appinventor.components.runtime.Form
Definition: Form.java:126
com.google.appinventor.components.runtime.errors.RuntimeError
Definition: RuntimeError.java:16
com.google.appinventor.components.runtime.util.FileUtil.getExternalFile
static File getExternalFile(String fileName)
Definition: FileUtil.java:519
com.google.appinventor