【问题标题】:Phonegap - How to access file in www-folder?Phonegap - 如何访问 www 文件夹中的文件?
【发布时间】:2014-03-19 18:16:04
【问题描述】:

我看到了多种解决方案如何访问 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. file:///Users/UserName/Library/Application%20Support/iPhone%20Simulator/7.0/Applications/GUID/AppName.app/www/test.txt

谁能给我一个可行的解决方案?

【问题讨论】:

    标签: javascript ios cordova file-access


    【解决方案1】:

    我建议使用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);
    
      }
    
    };
    

    【讨论】:

      【解决方案2】:

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

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

      我认为对于您的解决方案,您必须为您的应用添加读取权限 --> config.xml

      &lt;feature name="http://api.phonegap.com/1.0/file" /&gt;

      【讨论】:

      • 通过 ajax 调用我可以访问文件的内容,但我需要一个带有 'resolveLocalFileSystemURI' 方法的 'FileEnty' 对象...我添加了该功能,但我仍然收到安全错误...看来我没有权限访问该文件
      【解决方案3】:

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

      您只需执行以下操作。

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

      获取 FS 和根路径后,您可以简单地使用 ajax 调用或 getjson 调用并设置适当的 dataType。它对我有用。

      还可以查看有用的文档: 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 ");
          };  
      };
      

      【讨论】:

        【解决方案4】:

        因为我刚遇到同样的问题但不想使用 jQuery,我想我也在这里发布我的解决方案。

        但在此之前要注意一点:Cordova / Phone Gap 的 www 文件夹中的文件作为所谓的资产存储在 Android 世界中,这意味着:

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

        如果您深入了解corresponding Android sources of 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) 上进行了测试。

        【讨论】:

        • 它在 iphone 应用程序中的工作方式是否相同?
        【解决方案5】:

        一个有效的技巧是将 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

        然后,在你的前端:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-16
          • 1970-01-01
          相关资源
          最近更新 更多