With File API it is possible load data from local files into the browser memory via Javascript. I'm accessing huge files (200MB and bigger) on a system that is low in available RAM (webapp on an mobile device). How can I use the W3C File API (or Cordovas File Api as a fallback) to partially load data (e.g. by specifying a byte range) from files?
The solution is to use File.slice(). Notice that File inherits from Blob and thereby receives its slice() method.
var blob = file.slice(startingByte, endindByte);
reader.readAsBinaryString(blob);
Source of this information is HTML5Rocks.com. A full example can be found there.
Related
Working in Chrome, loading a local html or JS file.
I found many examples of how to load a file that is selected using the Choose File input.
However, didn't figure out how to do it given a file name without using the Choose File input.
The Choose File input returns a File object.
How to create the File object without the Choose File input?
From the File API:
new File(
Array parts,
String filename,
BlobPropertyBag properties
);
But didn't figure out what the parts and properties would be.
Edit: Use case:
I have code coverage results generated as part of a test suite. It is stored as JSON (which is easy to read), but I need to display it with the source code.
So the feature is to load the source code and JSON data, and render them together on a web page using HTML and Javascript.
The file would be opened from the browser and lives on the local machine. There is no server.
The browser cannot load arbitrary files by name from your filesystem without special extensions or other shenanigans. This is a security policy to prevent random web sites from reading files from your hard disk as you browse the internet.
If you're down to do something special like if you want to write a chrome app, you could get access to some nice APIs for accessing the filesystem:
https://developer.chrome.com/apps/fileSystem
The File constructor doesn't read a file from the harddrive, but rater make a virtual file, consider this:
var file = new File(["some", "content"], "/tmp/my-name.txt");
var reader = new FileReader();
reader.onload = function() {
console.log(reader.result); // somecontent
};
No file will be read or stored on the clients machine.
If you are talking about creating files in nodejs then you should take a look at fs.
For security reasons all browsers don't support predefined values on file fields so the answer is you can't.
I need to add a browse button inside my Chrome extension. Users click it and choose a file. I then want to retrieve the file contents (bytes) and do some work on it.
I don't want to have to submit the file to a remote server and then get the response (if that's even doable from inside a Chrome extension), it should be all client-side.
Is this doable inside Chrome extensions?
You should be looking at the FileReader API.
The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.
A very good basic example of using this interface is in this question.
A minimal example: suppose that you have an <input type="file" id="file"> with a text file selected.
var file = document.getElementById("file").files[0];
var reader = new FileReader();
reader.onload = function(e){
console.log(e.target.result);
}
reader.readAsText(file);
If you need methods other than reading as text (i.e. binary data), see the docs.
Also, this is a good overview: Using files from web applications
Regarding your question it is totally feasible to load and process a file within an extension. I implemented it using message passing https://developer.chrome.com/docs/extensions/mv3/messaging/.
Here is an example of how you can implement it, in my case I used the input file to load an excel. This is my public repo.
https://github.com/juanmachuca95/gomeetplus
We are developing an app that is to download files from HTTP URLs, the extensions/file types of which we will not know until runtime. We've been following this tutorial as a starting point, but since we aren't dealing with images, it hasn't helped us.
The issue is that the code in the tutorial will get you a Blob object and I can't find any code that will allow us to either:
Convert the Blob to a byte array.
Save the Blob straight to the file system.
The ultimate goal is to seamlessly save the file at the given URL to the file system and launch it with the default application, or to just launch it from the URL directly (without the save prompt you get if you just call Windows.System.Launcher.launchUriAsync(uri);).
Any insight anyone might have is greatly appreciated.
Regarding downloading content into byte array:
Using WinJS.xhr with the responseType option as 'arraybuffer' will return the contents in ArrayBuffer. A javascript typed array can be instantiated from the ArrayBuffer for example UInt8Array. This way contents can be read into byte array. code should look something like this:
// todo add other options reqd
var options = { url: url, responseType: 'arraybuffer' };
WinJS.xhr(options).then(function onxhr(ab)
{
var bytes = new Uint8Array(ab, 0, ab.byteLength);
}, function onerror()
{
// handle error
});
Once you take care of permissions to save the file to file system either by user explicitly picking the save file location using SaveFilePicker or pick folder using folder picker - file can be saved on local file system. Also, file can be saved to app data folder.
AFAIK, html/js/css files from local file system or the app data cannot be loaded for security reasons. Although DOM can be manipulated under constraints, to add content. I am not sure of your application requirements. You might need to consider alternatives instead of launching downloaded html files.
I'm developing a FileShare application with webRTC. I want to implement the client in JavaScript/HTML. The code should be run on the clients browser.
I need to save them when downloaded via webRTC. The files can be quite big and I can't completely donwload them and save them in a array or blob before saving them to disk as a file.
Is there any API that allows me to save the file in chunks as I recieve them?
I have found so far Downloadify, FileSave.js and html5 FileWriterApi so far.
While the first two are not chunked and require me to first download the complete file to memory before saving, the FileWriterAPI is not available on most browsers.
As #jordan-gray suggested, saving the chunks in blobs and joining them to a larger blob might be a solution if:
Persistence of chunks is not needed (i.e. closing the browser will delete all chunks)
The file is persisted only by the user saving it to his own filesystem. The web application will not have access to the file once it is closed, unless the user gave access to the saved file again.
Possibly, if the file sizes are not too big (you'll have to benchmark to find that out). Chrome was behaving quite nice for me for chunks totaling at 1GB.
I've created a simple test for using blobs as chunks. You can play around with the different size and chunk numbers parameters:
var chunkSize = 500000;
var totalChunks = 200;
var currentChunk = 0;
var mime = 'application/octet-binary';
var waitBetweenChunks = 50;
var finalBlob = null;
var chunkBlobs =[];
function addChunk() {
var typedArray = new Int8Array(chunkSize);
chunkBlobs[currentChunk] = new Blob([typedArray], {type: mime});
console.log('added chunk', currentChunk);
currentChunk++;
if (currentChunk == totalChunks) {
console.log('all chunks completed');
finalBlob = new Blob(chunkBlobs, {type: mime});
document.getElementById('completedFileLink').href = URL.createObjectURL(finalBlob);
} else {
window.setTimeout(addChunk, waitBetweenChunks);
}
}
addChunk();
If you do need that persistence, the W3C File System API should support what you need. You can use it to write the chunks to separate files, and then when all the chunks are completed you can read them all and append them to a single file, and remove the chunks.
Note that it works by assigning a sandboxed filesystem for your application (for a given quota), and the files are only accessible to that application. If the files are meant to use outside of the web application, you might need the function for the use to save the file from the application filesystem to his "normal" filesystem. You can do something like that using the createObjectURL() method.
You are right about current state of browser support. A Filesystem API polyfill is available, which is based on IndexedDB (which is more widely supported) as a filesystem emulation backend. I did not test the polyfill on large files. You might run into size limits or performance limitations.
Did you check https://github.com/Peer5/Sharefest out ? It should cover your requirements
The idea: at the moment I have a script which watch for new images uploaded (from smartphone or tab) to a specific folder. The script moves image to some subfolder depending on image's name and append a row with corresponding data to specific spreadsheet.
Is it possible to fetch geo information from uploaded to Google Drive images (using smartphone) to put them to the spreadsheet? Searched over the API, but look there is no native function for that. Any 3rd-party solutions?
It is possible to accomplish your task (to get geo-data of uploaded images) using GAS. There is no GAS service performing it and I am almost sure now there is no a 3rd-party solution for your task. A brief scheme for the task is the following
to traverse all files in the image folder.
to open every file by using the DocsList.getFileById method
to check if the file data has required MIME-type. I assume, that JPEG files are most wanted to you. They have the image/jpeg MIME-type. The getContentType method of the BLOB class returns the data type.
for filtered files, to get the data by using the BLOB.getBytes method, find in the data the EXIF-matadata (see bellow), parse it and get the geotags. The geo-info stored as metada inside of image file and usually has EXIF format. There is a number of Javascript libraries which are able to read EXIF of JPEG files, for instance, this one. You can either write your own code which will perform this step or modify the exist library (if the library license permits it). The exist library modification should not be a problem.
to publish the retrieved geo-information to a spreadsheet.