Phonegap - 如何访问www文件夹中的文件?

时间:2014-02-19 12:11:26

标签: javascript ios cordova file-access

我看到了多个解决方案如何访问www文件夹中的文件,但没有解决方案适合我。我使用iOS模拟器在iOS下测试应用程序。
我想访问www文件夹中的文件test.txt

我目前的解决方案如下:

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
  3. 有人能给我一个有效的解决方案吗?

5 个答案:

答案 0 :(得分:2)

我建议使用PhoneGap文件插件提供的resolveLocalFileSystemURL方法。然后,您可以使用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);

  }

};

答案 1 :(得分:0)

我用这样的ajax加载我的语言文件......

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

我认为您的解决方案必须为您的应用添加阅读权限 - &gt; config.xml

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

答案 2 :(得分:0)

试试这个,我的部分功能。首先需要获取文件系统,然后获取根路径。修改它以满足您的需求。

您可以执行以下操作。

app_FileSystem对我来说是一个由GetAppFS分配的全局变量

获取FS和根路径后,您可以简单地使用ajax调用或具有相应dataType集的getjson调用。它对我有用。

另请查看有用的文档: http://docs.phonegap.com/en/3.3.0/cordova_file_file.md.html#LocalFileSystem

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 ");
    };  
};

答案 3 :(得分:0)

由于我遇到了同样的问题但又不想使用jQuery,我想我也在这里发布我的解决方案。

但在此之前有一个导入评论:Cordova / Phone Gap的www文件夹中的文件存储在Android世界中,即所谓的资产,这意味着:

  • 它们是.apk分发文件的一部分,该文件是压缩存档。 Android直接从此.apk文件中读取文件,而不是将这些文件分别存储在本地文件系统中。
  • 因此文件是只读的,无法使用Cordova File插件访问。

如果您深入了解corresponding Android sources of Cordova,您可以看到,Cordova会使用'file'方案过滤所有URI,其路径以'/ android_asset /'开头,并使用Android的资产访问功能专门处理它们。 (从iOS专家那里听到Cordova如何在他们的世界中处理它会很有趣。)

这意味着如果您需要访问文件内容,使用XMLHttpRequest的所有内容可能是访问www文件夹文件的唯一可移植方式。 (如果您只需要某些系统函数的文件路径,其他方法也可以使用。)

这是代码,filename是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)进行了测试。

答案 4 :(得分:0)

一个有用的技巧是{www}将www文件夹中的每个文件fs.download转换为Cordova的持久文件系统。查看我的original post

首先,在终端:

  1. npm install cordova-promise-fs
  2. cordova plugin add cordova-plugin-file --save
  3. cordova plugin add cordova-plugin-file-transfer --save
  4. 然后,在你的前端:

    import CordovaPromiseFS from 'cordova-promise-fs'
    
    const fs = CordovaPromiseFS({
      persistent: true,
      storageSize: 200 * 1024 * 1024,
      concurrency: 3
    })
    

    如果使用React,则必须在创建组件Class之前声明上述代码,而下面的代码应该在组件Class内的自己的函数中。有关详细信息,请参阅我的GitHub comment

    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)
      }
    )