Changing the name of a file with FileWriter - html

I wonder if it is possible to rename a file with FileWriter function. At this point, I can save my file without problem. But I'd like to change her name when saving. Here is my function:
function saveFile() {
var s = fileEntry.name;
var new_name = s.substring(0, s.lastIndexOf(".")) + ".min" + s.substring(s.lastIndexOf("."))
fileEntry.name = new_name;
fileEntry.createWriter(function(fileWriter) {
fileWriter.onerror = function(e) {
console.log("Write failed: " + e.toString());
};
var blob = new Blob([textarea.value]);
fileWriter.truncate(blob.size);
fileWriter.onwriteend = function() {
fileWriter.onwriteend = function(e) {
console.log("Write completed.");
};
// fileWriter.write(blob);
}
}, errorHandler);
}
I guess it's possible, but I can not find how.
Thank you in advance!

To do this you need to use the DirectoryEntry API. To write to a new file you will need to use getFile to create a new file and write the contents into it.
To do this you also need to have access to the directory where you want to create the new file, and also permissions to create a file there. If the directory is within your sandboxed file system, this isn't a problem.
If you want to create the file on the user's file system it is more complicated. The user will need to have given your app access to the folder (via chrome.fileSystem.chooseEntry) and your app will need to have the chrome.fileSystem.directory and chrome.fileSystem.write permissions.

Related

Phonegap / Cordova / HTML5 Create a CSV File to download

I need a little bit of help.
My question is: What is the right way to create a csv(/txt) file in a AndroidApp based on PhoneGap with Cordova and Javascript?
I am playing now a few days with phonegap and im really new in this direction. Now i have seen that since a few weeks the cordova-plugins are not supported anymore. (e.g.) And so im wondering how i can create/generate a csv with my app and provide it do be downloadable to the user?
Thanks in advance for your help.
What do you mean that cordova-plugins are not supported anymore?
Naturally you need to use cordova-plugin-file
Below is simple code snippet of how to do read/write operations on files with this plugin installed.
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (dir) {
dir.getFile('test.txt', {create: true}, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function () {
// Create a FileWriter object for our FileEntry (ver.json).
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function (e) {
writeCompleted = true;
//console.log('Write completed.');
};
fileWriter.onerror = function (e) {
writeError = true;
//console.log('Write failed: ' + e.toString());
};
// Create a new Blob and write it to ver.json
var blob = new Blob(['foo;bar;baz'], {type: 'text/csv'});
fileWriter.write(blob);
}, fileErrorHandler);
};
reader.readAsText(file);
}, function () {
console.log('onErrorReadFile');
});
}, fileErrorHandler);
});
After you created file in filesystem you can serve for download with simple <a> tag.

File field - Append file list

I have made me a simple file field:
<input type="file" name="pictures_array[]" multiple accept="image/*" id="page_pictures_array" />
and some HTML5 File API code to list the files:
$('.page-form #page_pictures_array').change(function(evt) {
var file, files, reader, _i, _len;
files = evt.target.files;
console.log(files);
$('#file-list').empty();
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
reader = new window.FileReader;
reader.onload = (function(file) {
return function(e) {
var src;
src = e.target.result;
return $("<li>" + file.name + " - " + file.size + " bytes</li>").prepend($('<img/>', {
src: src,
"class": 'thumb'
})).appendTo($('#file-list'));
};
})(file);
reader.readAsDataURL(file);
}
});
(cf. here)
However, since I expect my users to be very stupid indeed, I am sure they will choose one file, then click on the upload field another time to choose the next. However, the list of the <input type="file"> is reset each time with the newly chosen images.
How can I make sure the new files are appended to the <input>'s array so I don't get flooded with angry user comments?
I'm also looking for an answer to this, I think others already do that.
But if you look at the filelist W3 reference http://www.w3.org/TR/FileAPI/#dfn-filelist it says that its readonly....
Edit: It's a big code now, with some improvements, that make the copy/paste difficult. But I started to create one variable that saves all the tmp files.
var tmp_files = new Array();
Then when I add a new file I push the file to that array like this
tmp_files.push(file);
After all the insertions/removals (I have another var to save the deletions) when the user clicks to send the files I have this code that makes the formdata with the files I want
var data = new FormData(); var count = 0;
$.each(tmp_files, function(i, file){
if(del_files.indexOf(file.name)== -1){
data.append(count, file);
count++;
}
});
Then I just send the var data thru ajax and save them.
You can get them using $data = $_FILES;
Hope this helps you.

File.copyTo keeps old file name

I try the following code to copy a selected file to the storage directory:
private function onAddFileClick():void
{
m__file = new File();
m__file.addEventListener(Event.SELECT, onFileSelect);
m__file.browseForOpen("Select a sound", [c__filter]);
}
private function onFileSelect(e:Event):void
{
var l__target:File = File.applicationStorageDirectory.resolvePath("test.snd");
m__file.copyTo(l__target, true);
}
The copy works but the target file's name keeps the original file's name. If I try to copy a file name "Kalimba.mp3", the copy will be named "Kalimba.snd" and not "test.snd" as expected. The problem is that after the copy, my reference to the target file does not lead to anything since its nativePath sticks to "test.snd" which does not exist.
I use AIR 3.6 with Flex 4.6.
Renaming is done with File.moveTo().
copy first and then use moveTo() to rename it. Unless just moving it will do it for you! Obviously ;)
So after you copy:
var sourceFile:File = File.applicationStorageDirectory;
sourceFile = sourceFile.resolvePath("Kalimba.snd");
var destination:File = File.applicationStorageDirectory;
destination = destination.resolvePath("test.snd");
try
{
sourceFile.moveTo(destination, true);
}
catch (error:Error)
{
trace("Error:" + error.message);
}

File class AS3 / AIR: let user choose only save location, not file name or extension

When using browseForSave method, is it possible to let the user choose only the location of a file, and not the file name or the extension?
I'm creating an encrypted file, and I need its name and extensions not to be changed by the user.
Thx!
EDIT (AFTER SOLVED)
I was simply looking for the browseForDirectory method. Shame on me. :)
For a reference on how to open a browse dialog to choose a folder see the example here:
How to create "Browse for folder" dialog in Adobe FLEX?
once you have your directory you can piece that together with code here to save a file using the FileStream object:
http://blog.everythingflex.com/2008/02/25/file-and-filestream-within-air/
copied here since it's an external link
private function saveFile():void{
var myPattern:RegExp = / /g;
var newFileName:String = fileName.text.replace('.txt','');
if(newFileName.length > 1){
var file:File = File.desktopDirectory.resolvePath("Files/" + newFileName.replace(myPattern,'_') + ".txt");
var stream:FileStream = new FileStream()
stream.open(file, FileMode.WRITE);
var str:String = contents.text;
str = str.replace(/\r/g, File.lineEnding);
stream.writeUTFBytes(str);
stream.close();
fdg.directory = File.desktopDirectory.resolvePath("Files/");
fileName.text = "";
contents.text = "";
} else {
mx.controls.Alert.show("File name is required", "Error Saving File");
}
}
One solution would be to set the file object like this:
var f:File = File.desktopDirectory.resolvePath("*.txt");
f.addEventListener(Event.SELECT, onSelected);
f.browseForSave("save txt file");
Although user can still override that in the opened dialog, but at least the dialog shows the file extension. And later in the Event.SELECT you can check and confirm what user has selected.

Recursive Folder/Directory Copy with AS3 /Air

Is it possible to use pause/resume function to this??
source.copyTo( destination );
It would be great if you can send it at the earliest.
I found one solution here CookBook from Adobe
private function copyInto(directoryToCopy:File, locationCopyingTo:File):void
{
var directory:Array = directoryToCopy.getDirectoryListing();
for each (var f:File in directory)
{
if (f.isDirectory)
copyInto(f, locationCopyingTo.resolvePath(f.name));
else
f.copyTo(locationCopyingTo.resolvePath(f.name), true);
}
}
Or you could just use the File.copyTo() method:
var source:File = new File();
source.resolvePath( 'sourceFolder' );
var destination:File = new File();
destination.resolvePath( 'destinationFolder' );
source.copyTo( destination );
If the directories are large and you don't want your app to be stuck waiting for the copy, you can use copyToAsync, which will cause the source file to dispatch Event.COMPLETE when the job's done.
Here is the modified code from above if anyone wants to copy the entire directory; empty folders and all. Notice the "copyEmptyFolders" parameter to be used in the arguments.
//Recursivley copies directory.
private static function copyInto(directoryToCopy:File, locationCopyingTo:File, copyEmptyFolders:Boolean=true):void
{
var directory:Array = directoryToCopy.getDirectoryListing();
for each (var f:File in directory)
{
if (f.isDirectory)
{
// Copies a folder whether it is empty or not.
if( copyEmptyFolders ) f.copyTo(locationCopyingTo.resolvePath(f.name), true);
// Recurse thru folder.
copyInto(f, locationCopyingTo.resolvePath(f.name));
}
else
f.copyTo(locationCopyingTo.resolvePath(f.name), true);
}
}