问题
I saw multiple solutions how to access a file in the www folder but no solution works for me. I test the application under iOS with the iOS-simulator.
I want to access the file test.txt
in the www folder.
My current solution looks like this:
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;
};
This solution does not work for me. I get an error with errorCode = 2
which obviously means FileError.SECURITY_ERR
. However I try, with resolveLocalFileSystemURI
I can not access to the file.
INFO: I tried following filePathURI
:
- /Users/UserName/Library/Application%20Support/iPhone%20Simulator/7.0/Applications/GUID/AppName.app/www/test.txt
- file:///Users/UserName/Library/Application%20Support/iPhone%20Simulator/7.0/Applications/GUID/AppName.app/www/test.txt
Can anyone give me a working solution?
回答1:
I would suggest utilizing the resolveLocalFileSystemURL
method provided by PhoneGap's file plugin. You can then use the cordova.file.applicationDirectory
property to access where your www
folder is located.
Make sure you install the plugin: $ cordova plugin add org.apache.cordova.file
Then you could use an object such as the following to parse the files and do whatever is needed:
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:
I load my language files with ajax like this...
$.get( "test.txt", function( data ) {
console.log( "Load was performed.", data );
});
I think for your solution you have to add read access to your app --> config.xml
<feature name="http://api.phonegap.com/1.0/file" />
回答3:
Try this, part of my functions. You first need to get the file system and then get the root path. Modify it to fit your needs.
The you just can do the following.
app_FileSystem for me is a global variable that gets assigned by GetAppFS
After getting the FS and the root path you can just simple use a ajax call or a getjson call with the appropriate dataType set. It works for me.
Also check the doc which is helpful: 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:
As I just ran into the same problem but did not want to use jQuery, I thought I post my solution here as well.
But before that an import remark: The files in the www folder of Cordova / Phone Gap are stored in the Android world as so called assets which means:
- They are part of the .apk distribution file which is a zipped archive. Android reads the files directly from this .apk file and does not store these files separately in the local file system.
- Therefore the files are read only and cannot be accessed with the Cordova File plugin.
If you take a deep dive in the corresponding Android sources of Cordova you can see, that Cordova filters all URIs with a 'file' scheme, whose path starts with '/android_asset/' and handles them specially using Android's asset access functions. (Would be interesting to hear from the iOS experts how Cordova handles it in their world.)
This means all in all that using a XMLHttpRequest is probably the only portable way to access www folder files if you need access to the file contents. (If you only need the path to the file for some system functions other methods may work as well.)
Here is the code, filename is the path within the www folder without a "www/" prefix:
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();
};
This has been tested with Cordova 4.3.0 and Android 4.4.2 (Kitkat).
回答5:
One trick that works is to fs.download
each file from the www folder into Cordova’s persistent file system. See my original post.
First, in Terminal:
npm install cordova-promise-fs
cordova plugin add cordova-plugin-file --save
cordova plugin add cordova-plugin-file-transfer --save
Then, in your front-end:
import CordovaPromiseFS from 'cordova-promise-fs'
const fs = CordovaPromiseFS({
persistent: true,
storageSize: 200 * 1024 * 1024,
concurrency: 3
})
If you use React, the above has to be declared before the component Class
is created, while the below code should be in its own function inside the component Class
. See my GitHub comment for more details.
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)
}
)
来源:https://stackoverflow.com/questions/21880109/phonegap-how-to-access-file-in-www-folder