== HTML5_FileSystem APIs _Tutorial ==
	** Update :
	
	== HTML5_FileSystem APIs Async_Tutorial ==
	** HTML5ROCKS : http://www.html5rocks.com/en/tutorials/file/filesystem/
	
	[ The Categories of FileSystem APIs ]
	>	Reading and manipulating files: File/Blob, FileList, FileReader
	>	Creating and writing: BlobBuilder, FileWriter
	>	Directories and file system access: DirectoryReader, FileEntry/DirectoryEntry, LocalFileSystem

	[ The Structure of FileSystem APIs ]
	>	File APIs: Directories and System
		*	FileSystem
				1) Represent a file system
				2) Will be passed as the argument of a successful callback of window.requestFileSystem()
		*	Entry
			-	DirectoryEntry : Entry
					1) Represent an entry to access directory in a file system
					2) FileSystem.root is the instance of DirectoryEntry
					3) Will be passed as the argument of a successful callback of DirectoryEntry.getDirectory()
			-	FileEntry : Entry
					1) Represent an entry to access file in a file system
					2) Will be passed as the argument of a successful callback of DirectoryEntry.getFile()
		*	DirectoryReader
				1) The object to read a list of entries from a specific directory.
				2) Returned by calling DirectoryEntry.createReader()
	>	File APIs: Writer
		*	BlobBuilder
				1) The object to construct Blobs
				2) Returned by calling new BlobBuilder();
		*	FileSaver
			-	FileWriter : FileSaver
					1) The object to multiple write actions, saving a single Blob
					2) Will be passed as the argument of a successful callback of fileEntry.createWriter()
	
	[ How to Access Files ]
	1)	Reuqest a FileSystem by calling window.requestFileSystem(   )
		1-1) Request the quota for the PERSISTENT storage if neccessary
	2)	Get the DirectoryEntry of the root directory of the FileSystem, which is FileSystem.root
	3)	Get/Create the sub directory under the root by calling FileSystem.root.getDirectory(path, )
	4)	Get/Create the FileEntry of file under the specific directory by calling DirectoryEntry.getFile()
	5)	Get the file by calling FileEntry.file()
	6)	Manipulate the file
	
	[ Manipulate Files ]
	*	Read the file:
			-	using the FileReader object, say, FileReader.readAsText(file)
			-	do sth when reading is done by registering a FileReader.onloadend event
	*	Write to the file:
			-	getting the FileWriter object by calling FileEntry.createWriter(successCallback, errorCallback)
			-	using the FileWriter object to write, say, FileWriter.write(bb.getBlob('text/plain'))
	*	Modify the file content:
			-	before write to the file, move the index to the desired position by calling FileWriter.seek(theDesiredPosition)
	*	Remove the file:
			-	calling FileEntry.remove(successCallback, errorCallback)
	*	Copy user-selected files:
			-	get the file selected, say,
				<input type="file" id="myfile" multiple />
				document.querySelector('#myfile').onchange = function(e) {
					var files = this.files;
				
					function copyFiles(fileSystem) {
					// Duplicate each file the user selected to the app's fs.
						for (var i = 0, file; file = files[i]; ++i) {
							// Capture current iteration's file in local scope for the getFile() callback.
							fileSystem.root.getFile(file.name, {create: true, exclusive: true}, function(fileEntry) {
								fileEntry.createWriter(function(fileWriter) {
									fileWriter.write(file); // Note: write() can take a File or Blob object.
								}, errorHandler);
							}, errorHandler);
						}
					}
					
					window.requestFileSystem(window.TEMPORARY, 1024*1024, copyFiles, errorHandler);
				};
	
	[ Manipulate Directories ]
	>	Create a subdirectory
			-	using DirectroyEntry.getDirectory()
			-	the error arises when attempting to create a directory whose immediate parent does not exist.
				The solution is to create each level directory in a loop or recursively.
	>	Read a directory
			-	keep calling DirectroyEntry.DirectoryReader.readEntries() until no more results are returned.
	>	Remove a directory
			-	calling DirectroyEntry.remove(successCallback, errorCallback)
			-	attempting to delete a non-empty directory results in an error.
				The solution is to remove each level directory in a loop or recursively.
	
	[ Common Manipulation ]
	>	Copy a File/Directory
			-	using FileEntry/DirectroyEntry.copyTo(destinationDirectoryEntry)
			-	This method automatically does a recursive copy on folders.
	>	Move/Rename a File/Directory
			-	using FileEntry/DirectroyEntry.moveTo(newParentDirectoryEntry, optionalNewFileName)
			-	by keeping the origin DirectoryEntry as the new parent DirectoryEntry and giving an new name,
				we can rename a File/Directory
	
	[ FileEntry to URL ]
	>	calling FileEntry.toURL(), we can convert the URL to the FileEntry, say
			-	document.createElement('img').src = fileEntry.toURL(); // filesystem:http://example.com/temporary/myfile.png
	>	calling window.resolveLocalFileSystemURL(theFileEntryURL, successCallback, opt_errorCallback),
		we can convert the FileEntryURL back to the FileEntry	
	
	[ Callback Hell ]
	>	In order to achieve asynchronous operations, async FileSystem APIs use
		callbacks a lot (layers on layers of callbacks), so the developer is easily to get lost in the Callback Hell.
		Fortunately, we can escape from the Callback Hell, yet still working in the asyncronous state,
		please refer to Sync FileSystem APIs and Web Workers.
	
	
	== HTML5_FileSystem APIs Sync_Tutorial ==
	** HTML5ROCKS : http://www.html5rocks.com/en/tutorials/file/filesystem-sync/

	[ Sync vs. Async ]
	>	For the most part, the synchronous API is exactly the same as its asynchronous cousin.
	>	The major deviations are:
			*	The synchronous API can only be used within a Web Worker context,
				whereas the asynchronous API can be used in and out of a Worker.
			*	Callbacks are out. API methods now return values, for example,
					-	In Async context, the FileEntry are thrown into the successCallback of DirectoryEntry.getFile()
					-	In Sync context, the FileEntry are returned by DirectoryEntry.getFile()
			*	The methods are appended with "Sync", say, requestFileSystemSync(), FileEntrySync, etc...

	[ Self, not Window ]
	>	In the WebWorker scope, use self.requestFileSystemSync() instead of window.requestFileSystem()

	[ Deal with Quota ]
	>	Currently, it's not possible to request PERSISTENT quota in a Worker context.
	>	The workaround solution
			1)	worker.js: Wrap any FileSystem API code in a try/catch so any QUOTA_EXCEED_ERR errors are caught.
			2)	worker.js: If you catch a QUOTA_EXCEED_ERR, send a postMessage('get me more quota') back to the main app.
			3)	main app: Go through the window.webkitStorageInfo.requestQuota() dance when #2 is received.
			4)	main app: After the user grants more quota, send postMessage('resume writes') back to the worker to inform it of additional storage space.

	[ How to Handle Error without The errorCallBack ]
	>	Catch the error, then post the error message to the main page, say,
			Function reportError(err) { postMessage('ERROR: ' + err.toString() ); }
			try {
				// When error ocurrs, error would be thrown to the catch block below.
			} catch (err) {
				reportError(err);
			}
	
	[ Passing around Files, Blobs, and ArrayBuffers ]
	>	Post the messages(files) to the main page upon completing manipulating the files
	>	According to browser support, the data types could be messaged are
			*	String => all browers support
			*	JSON object => all browsers support (should be)
			*	Files, Blobs, and ArrayBuffers => browser capable of structured clone algorithm supports, say, Chrome
			
	[ Access the same FileSystem ]
	>	Utilize FileSystem: URL
			1)	get the FileSystem: URL by calling DirectoryEntry/FileEntry.toURL()
			2)	post the FileSystem: URL to the main page
			3)	retrieve the DirectoryEntry/FileEntry by calling
				window.resolveLocalFileSystemURL() / window.resolveLocalFileSystemSyncURL()
			4)	Having the same DirectoryEntry/FileEntry, the main page and the worker page can access the same FileSystem
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Foxbrush 的頭像
    Foxbrush

    Foxbrush

    Foxbrush 發表在 痞客邦 留言(0) 人氣()