I have a single text input box where user enters a path to a directory. I want to fetch names of all the files from that directory using File API in JavaScript.
I was reading from this article: http://www.html5rocks.com/en/tutorials/file/filesystem/#toc-dir and tried executing the code under Reading a Directory's contents but was unable to understand the code since we are mentioning the directory name anywhere in the code.
So, how can i accomplish my task?
As far as the SPECS are concerned,
It is not possible to read normal file system directories from the browser apart from the upload button / flash etc.
The browser can, however create a sandbox (in its user files) which appears as a directory structure you can manipulate. This is useful for apps that need to play with actual files and store them locally rather than on server.
Real Life story
The filesystem API is not supported, rather dead specs which may find its way to implementation if need arise.
Nearest currently working functionality is local storage
Related
I'm working on an app that needs to access a collection of external files. It's basically a music player. It works as-expected under a web server, but I also want it to work locally in the browser.
General overview:
index.htm (Small index file with markup, gather external js, css)
index.js (All the app code here)
dir.js (An array of file paths of all music files)
/AHX/ (location of the music files)
ahx.js (music player code)
The two main difficulties for this are:
JavaScript cannot list directory contents, even if it is a child directory. Instead I express file paths as an array of strings.
Loading external files only possible using XMLHttpRequest, which has security restrictions when running local/offline, but works in other environments (under HTTP or Chrome App, perhaps other platforms, not sure).
Oddly, in the latest Firefox, 2) is not an issue anymore. XMLHttpRequest works locally without disabling security.fileuri.strict_origin_policy. I'm not sure if that is standard behavior, but Chrome doesn't appear to allow it.
In any case, my current solution is generating a list of file-paths in a .js file (previously I used a txt file that required XHR), and using XMLHttpRequest to load the music files. This of course means I need to keep the folder structure and the file-path database in sync, using a shell script to rebuild the dir.js file.
XHR is only supposed to work over HTTP, so the app requires a web server. I want the app to work locally (and not just force the user to install as a Chrome App). So I am asking this question to find alternative methods of reading the data.
One alternative I tried is encoding all 1000 files in base64 strings and storing it in a JS object. This produces a rather large 8MB .js file. It doesn't appear to be slow to load, but I am assuming it isn't exactly efficient... Plus it is a pain to update/maintain.
localStorage, IndexedDB and Web SQL are all options, but there is no way to pre-populate the storage before the app runs. Perhaps utilize File API for a one-time setup of the storage database.
So back to my question: What are some solutions to accessing a large collection of binary files (200+ files, over 6MB etc) locally (i.e. opening the .html file directly)?
Edit: The app in question on GitHub, to clear up any confusion on my use case. But in general, I'm looking for ways to automatically read these music files from the app locally, without cross-origin errors. Also, here is the 'js-database' version. It stores all 1000 files in a 8MB js file likes so:
[{data:"base64-string-of-data-here",path:"original-path-here"}, ...]
In that way it bypasses the need for XHR.
Edit2: A solution using jszip and IndexedDB appears promising. It is not possible to load multiple files from multiple selected folders, but if the directory tree is zipped, jszip can access an array of all files in the format /FOLDER_HERE/FILE_HERE. The paths and binary data can then be imported into IndexedDB in a one-time setup. It also works fine on file:// URLs which is important.
It is also possible that jszip could be used to effectively build/update a large JSON structure of BASE64 strings of the contents, which doesn't require any setup by the user. Still need to be tested though.
don't take this as a definitive answer, this subject interests me too, if people around dont want to take time to elaborate an answer, please comment, it will be more useful than votes..
from what i learnt in javascript resources, consider that you cannot really bypass the security aspect of the question. Even open source, you should warn explicitly if you didn't take in account the security. People could distribute a modified version of the resources for example. It depends on what is done with the resources.
If this is for a player i recommend treating it as a data resource, not as a script resource, because of security (as long as you don't eval strings or such). JSON data could do the job here, but that would need to process the 1000 files. Not so hard to write a script that processes the files though.
HTML5 file API
I haven't used it yet, so i can just give you one or two links. With the downside that it restricts your player to recent browsers.
https://www.html5rocks.com/en/tutorials/file/dndfiles/
HTML5 File API read as text and binary
(i know, not an answer) use a library:
Except that in this case, this might be an answer, just because there is no real universal data retreivement in javascript. A good library would add that and a support for old browers.
Among these solutions, for example jQuery JSONP allows to do dynamical cross-domain GET requests. With data formatting (and not script), it is much safer to inject. But keep in mind that you should be aware in detail what your player does with the binary, and in which way it can be a risk.
http://api.jquery.com/jQuery.getJSON/
direct inclusion of script: not recommended
<script src="./sameFolderFile.js"></script>
As for direct script inclusion in a local folder structure, it actually works in local. IE says there is ActiveX content and asks for use permission, but it works in firefox and chrome. The tag can be dynamically added, but there is a big security risk here: malicious javascript code added in the resources will be executed. This can lead to risks for the users
I know that JavaScript is not allowed by browsers to do much directly with the computer, and that is not my question. My question is: How to, with JavaScript, create a file on the web and then ask, perhaps with a popup window, to download the folder and any files within. This folder would need to allow access for JavaScript to place files within, like image files. This folder might originally be just another JavaScript value (like an object) or a URL.
I have done research, but much of what I found was asking whether JavaScript could create a folder directly to the computer, while my question is asking about creating the folder, and then asking to download it. There must be some way, because when in Google Drive, drive has a way to place multiple files in a .zip folder for download, and this works not just with Chrome but with Firefox and Internet Explorer. Some sites like http://stuk.github.io/jszip/ provide their own way to create .zip files, but I would prefer not to use a JavaScript library, if possible.
This would be useful for generating multiple image files, but only asking the user once for downloading them, instead of for each file.
I would prefer to create the zips client-side.
So this is an interesting question and I shall do my best to answer it. The simple solution is to not do this at all. Use javascript to asynchronously request the server to create the required .zip and then give the user a link/prompt to download. But I digress, you want it all in-house!
JSzip Option
You'll not be able to write a solid library that can .zip files client-side. JSzip is the best option out there, and it's not as solid as it could be. If you have the time you could go through the source and make improvements where required.
Cheeky Option
Your best option - baring the actual best one (server side) which you have discounted - is explained here. That is - create an iframe for each file.
Unfortunately you'll not find any better than those options if you're insisting on client-side work. Browsers weren't made to be zipping files.
I have a text file i want to read in my html page,both are in the same directory and i am not running a server. I intend that my users use the script offline(basically text manipulation based on expressions and preserving new line characters) .
I tried ajax call but mostly cross domain origin problem occured and i know most of the users will have this security tighened up in many browsers , so its not of use to circumvent this in only in my browser.
I want to support many browsers including old browsers as in IE7,8 etc which do not support HTML5 filereader.for the same reason reading using filesystemobject or activex is not good.
Reading the file after user select it as input , is this possible?Otherwise i would have no option then using other technologies like php,java etc which may expect my user to setup these.
Please excuse me if i am repeating this but i am a beginner web developer. I know that reading local files via javascript is not possible but is there any other way?
If you can't support FileReader, then the answer is pretty much no (at least, if you want to support a large range of browsers rather than rely on convenient feature x of browser y). Unless : you indeed increase the requirements for running the application and get some sort of local server going (for instance node.js, Apache, TomCat, etc. but like you said this will greatly increase the requirements and become cumbersome for users).
You could also rethink what it is you're trying to achieve. What are the contents of the file you want to read ? Can't these contents be part of the HTML file you're serving to your users (i.e. a large JSON Object inside a script-tag ?)
On possibility of using node.js:
Node.js is quite easy to install and assuming you are requiring from your users to install it, you can use it as a local server, which is a nodejs script of about two lines in size :). Running it locally would also omit the need to upload anything anywhere as you can directly read from the file system using the fs-object (see sitepoint.com/accessing-the-file-system-in-node-js).
STILL: from both a design and ease-of-use-point of view you might want to resort to using either another technology, or include the text file content inside the HMTL file
I've been doing Code Year at Codecademy and I wanted to start practicing Javascript for myself, but I've been having a tough time figuring out some basic issues.
For my first project, I want to read in from a spreadsheet. I can't figure out how to access the data from its original source online, so I thought I would just save it as a text file. My question, then, is how to read from that.
So it looks like you can't read local files in Javascript. (Although apparently that's changing with HTML5? I don't have any familiarity with that.) So do I have to upload the text file someplace? Can I upload files to JS Bin? If not, does anyone have any recommendations for where I can upload the text file? And either way, once I do, what's the code to read from it?
Thanks in advance. I am sure this question is riddled with misstatements and improprieties, but I've spent a significant amount of time on this and I can't find anything that seems to answer my question. I honestly thought it would be something simple, like "var inputfile = c:\file.txt" but that seems not to be the case. I am totally lost. Thanks!
You can't. File system and storages in Javascript (or rather the client) is sandboxed.
That means you can only read what is written there in the first place. This has to do with security.
You will need to drop (or select) the local files into the browser and have some mechanism there to receive the drop/selection and store the file to one of the local storing mechanisms such as indexedDB or file API (the latter currently only supported in Chrome). For text files localStorage works fine too.
Resources:
http://updates.html5rocks.com/2011/08/Saving-generated-files-on-the-client-side
http://www.w3schools.com/html/html5_webstorage.asp
http://www.w3.org/TR/webstorage/
http://www.w3.org/TR/FileAPI/
http://www.w3.org/TR/IndexedDB/
The other option is to upload it to server and download it from there when you need it.
When you get to this point in your development, its time to run your own webserver for testing as it makes things much easier. If you must insist on doing it your way, uploading the file to a file hosting site and reading it in is still possible. Codecademy is great for getting started, but when you get into dealing with persistent data sources (either files or databases) its time to get web hosting or set up your own test server.
Even then you don't REALLY need your own test server, just a folder on your computer. You can access the files with File://, and link in the file you want to read as a relative path. If the .txt file is in the same directory, you just link it in as "Example.txt" when you open the html file in that directory.
I'm building an HTA application in which I need to display a list of file with their associated system icon.
I'm using FileSystemObject to list the file but there seem to have no way to get the icon...
I've found a script in VBS that can save the icon of a file into a .ico .
It read the file (PE resource file, .exe or dll) and parse the icon data.
I modified that script to return the icon's bytes, convert it to base64 and use embed base64 images in HTML.
Here's the original script: http://gilpin.us/IconSiphon/
Issue
) In most case the .ico contains multiple icons (many sizes and color depth) but there's no way I can specify which one to use (as I need 16x16 icons).
) Not all icons are displayed
) Could be slow with many file as it read exe and dll (but I'm ok with that, I can cache already fetched icon)
I've also tried some ActiveX control but none seem to work properly. Even those provided by microsoft (ShellFolderView or ListView) are very buggy.
Requirements
Must display 16x16 icon
Must allow multiple file selection
Everything must be embed in hta (if possible). No external .exe
Does anyone know a way to achieve that?
Thanks!
Use SHGetFileInfo() with the SHGFI_ICON flag.
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762179(v=vs.85).aspx
The filesystemobject will provide you the necessary functions for enumerating files on the local filesystem. However to get the icon image you will need to use the win32 api per #seanchase's response or an external exe.
However you can access the win32api via javascript in the hta using the wshApiToolkit activex object - http://www.google.com/search?q=wshAPIToolkit.ucATO%2F&rls=com.microsoft:en-us&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1
Find a copy of that and you're close to being done. It does require distributing the activex object with your code and shell executing the registration process from within the HTA so that might violate your third constraint. Though I believe you can base64 encode the exe into the hta in a dataurl and write that back out to the file system so it would at least be bundled into a single file. If you support that option then maybe embedding an exe that does the same would meet your requriements.
Definitely some hacky stuff that may be unstable on future OS versions - heck I'm not even sure the wshApiToolkit works on windows 7, and 8 is just around the corner. Good luck!
You indicated you're opened to installing ActiveX components and using them in your HTA.
If I had the time, I would approach this for myself by creating ActiveX components using Visual Studio to call FindResource, LoadResource and LockResource. These will enable access to the Group Icon resource for which I would then provide rich interfaces to iterate through the Icons offering the ability to extract BMPs (or PNGs).
This is "how" I would go about achieving this short of actually going off doing it.
Once I build a similar HTA interface and I faced the same problem. I solved the problem by creating a custom icon gallery and converting the images using base64. You may achieve the same by either converting or using sprite. Many UI does it, even java.swing has its own collection embbebed. As you noticed, reading from *.dll can speed down the application