Phonegap - Как получить доступ к файлу в www-папке?

Я видел несколько решений, как получить доступ к файлу в папке www, но ни одно решение не работает для меня. Я тестирую приложение под iOS с помощью iOS-симулятора.
Я хочу получить доступ к файлу test.txtв папке www.

Мое текущее решение выглядит так:

var filePathURI = getPhoneGapPath() + "test.txt";
window.resolveLocalFileSystemURI(filePathURI, onResolveSuccess, onFail);

function getPhoneGapPath() {  
    'use strict';
    var path = window.location.pathname;
    var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
    return phoneGapPath;
};

Это решение не работает для меня. Я получаю ошибку с errorCode = 2 что, очевидно, означает FileError.SECURITY_ERR, Однако я стараюсь, с resolveLocalFileSystemURI Я не могу получить доступ к файлу.

ИНФОРМАЦИЯ: Я пытался следовать filePathURI:

  1. /Users/UserName/Library/Application%20Support/iPhone%20Simulator/7.0/Applications/GUID/AppName.app/www/test.txt
  2. Файл:///Users/UserName/Library/Application%20Support/iPhone%20Simulator/7.0/Applications/GUID/AppName.app/www/test.txt

Кто-нибудь может дать мне рабочее решение?

5 ответов

Я бы предложил использовать resolveLocalFileSystemURL метод, предоставляемый файловым плагином PhoneGap. Затем вы можете использовать cordova.file.applicationDirectory собственность для доступа, где ваш www папка находится.

Убедитесь, что вы установили плагин: $ cordova plugin add org.apache.cordova.file

Затем вы можете использовать такой объект, как следующий, чтобы проанализировать файлы и сделать все необходимое:

var FileManager = {

  /**
   * Execute this.entryHandler against all files and directories in phonegap's www folder
   */
  run: function () {

    window.resolveLocalFileSystemURL(
      cordova.file.applicationDirectory + 'www/',
      this.directoryFoundHandler,
      this.errorHandler
    );

  },

  /**
   * The directory has been successfully read.  Now read the entries.
   *
   * @param {DirectoryEntry} directoryEntry
   */
  directoryFoundHandler: function (directoryEntry) {

    var directoryReader = directoryEntry.createReader();

    directoryReader.readEntries(
      this.entryHandler,
      this.errorHandler
    );

  },

  /**
   * Files were successfully found.  Parse them!
   *
   * @param {Array.<FileEntry>} entries
   */
  entryHandler: function (entries) {

    entries.forEach(function (entry) {

      // Deal with your files here
      if (entry.isDirectory) {
        // It's a directory might need to loop through again
      } else {
        // It's a file, do something
      }

    });

  },


  /**
   * @param {FileError} error
   */
  errorHandler: function (error) {

    console.log("ERROR", error);

  }

};

Поскольку я столкнулся с той же проблемой, но не хотел использовать jQuery, я решил опубликовать здесь и свое решение.

Но до этого примечание об импорте: файлы в папке www Cordova / Phone Gap хранятся в мире Android как так называемые активы, что означает:

  • Они являются частью дистрибутивного файла.apk, который является архивом. Android считывает файлы непосредственно из этого файла.apk и не хранит эти файлы отдельно в локальной файловой системе.
  • Поэтому файлы доступны только для чтения и недоступны с помощью плагина Cordova File.

Если вы глубоко погрузитесь в соответствующие Android-источники Cordova, то увидите, что Cordova фильтрует все URI по схеме "файл", путь которой начинается с "/android_asset/", и обрабатывает их специально, используя функции доступа к ресурсам Android. (Было бы интересно услышать от экспертов по iOS, как Cordova справляется с этим в их мире.)

В целом это означает, что использование XMLHttpRequest, вероятно, является единственным переносимым способом доступа к файлам папки www, если вам нужен доступ к содержимому файла. (Если вам нужен только путь к файлу для некоторых системных функций, другие методы также могут работать.)

Вот код, имя файла - это путь в папке www без префикса "www/":

var readFileInWWWFolder = function(filename, onSuccess, onFailure){

    var request = new XMLHttpRequest();

    request.onload = function() {

        var arrayBuffer = request.response;

        if (arrayBuffer) {

            onSuccess(new Uint8Array(arrayBuffer));
        }
        else {

            onFailure();
        }
    };

    request.open("GET", filename, true);
    request.responseType = "arraybuffer";
    request.send();
};

Это было протестировано с Cordova 4.3.0 и Android 4.4.2 (Kitkat).

Один трюк, который работает, это fs.download каждый файл из папки www в постоянную файловую систему Cordova. Смотрите мой оригинальный пост.

Сначала в Терминале:

  1. npm install cordova-promise-fs
  2. cordova plugin add cordova-plugin-file --save
  3. cordova plugin add cordova-plugin-file-transfer --save

Затем в вашем интерфейсе:

import CordovaPromiseFS from 'cordova-promise-fs'

const fs = CordovaPromiseFS({
  persistent: true,
  storageSize: 200 * 1024 * 1024,
  concurrency: 3
})

Если вы используете React, вышеуказанное должно быть объявлено до компонента Class создается, в то время как приведенный ниже код должен быть в своей собственной функции внутри компонента Class, Смотрите мой комментарий GitHub для более подробной информации.

window.resolveLocalFileSystemURL(
  cordova.file.applicationDirectory + 'www/epubs/alice.epub',
    // If successful...
    (fileSystem) => {
      const downloadUrl = fileSystem.toURL()
      const localUrl = 'alice.epub' // the filename it is stored as in the device
      fs.download(
        downloadUrl,
        localUrl,
        (progressEvent) => {
          if (progressEvent.loaded && progressEvent.total) {
          console.log('progress', Math.round((progressEvent.loaded / progressEvent.total) * 100))
        }
      }
    ).then((filedata) => {
      return fs.toInternalURL(localUrl)
    })
    .then((localPath) => {
      this.setState({ epubPath: localPath })
    }).catch((error) => {
      console.log('some error happend', error)
    })
  },
  // If unsuccessful
  (err) => {
    console.log(err)
  }
)

Я загружаю свои языковые файлы с помощью ajax, как это...

$.get( "test.txt", function( data ) {
  console.log( "Load was performed.", data );
});

Я думаю, что для вашего решения вы должны добавить доступ для чтения к вашему приложению -> config.xml

<feature name="http://api.phonegap.com/1.0/file" />

Попробуйте это, часть моих функций. Сначала вам нужно получить файловую систему, а затем получить корневой путь. Измените его в соответствии с вашими потребностями.

Вы просто можете сделать следующее.

app_FileSystem для меня - это глобальная переменная, которая присваивается GetAppFS

После получения FS и корневого пути вы можете просто использовать вызов ajax или вызов getjson с соответствующим набором dataType. Меня устраивает.

Также проверьте документ, который является полезным: http://docs.phonegap.com/en/3.3.0/cordova_file_file.md.html

app_FileSystem.root.fullPath; // Get the app file system root full path

function GetAppFS ()
{
    var self = this;
   self.state = "";                     // store the state of the process for debuggin purposes
   self.fileSystem = {};

    window.requestFileSystem ( LocalFileSystem.PERSISTENT, 0, getFileSystemSuccess, dispatchFailure );

    /**
     *
     * Called when we receive a valid file system. Once we do that, we need to ask for all
     * the documents within the file system.
     *
     */
    function getFileSystemSuccess ( fileSystem )
    {
        self.state = "Received File System";
         self.fileSystem = fileSystem;
        app_FileSystem = fileSystem;
         OnFSReady ();
    };

    /**
     *
     * All our functions need a failure callback, so we provide dispatchFailure. If an error occurs, we'll
     * at least log it to the console, and then call the failure function attached to self.failure(), if any.
     *
     */
    function dispatchFailure ( e )
    {
        // some sort of failure :-(
        console.log ("While " + self.state + ", encountered error: " + JSON.stringify(e));
         alert ("dev FS ERROR ");
    };  
};
Другие вопросы по тегам