HTML5之本地文件系统API - File System API

HTML5之本地文件系统API - File System API

2014-06-03 17:54 19991人阅读 评论(0) 收藏 举报

目录(?)[+]

新的HTML5标准给我们带来了大量的新特性和惊喜,例如,画图的画布Canvas,多媒体的audio和video等等。除了上面我们提到的,还有比较新的特性 - File System API,它能够帮助我们来突破沙箱访问我们本地的文件系统,从而有效的弥补桌面和web应用之间的鸿沟。在今天这篇文章中,我们将会介绍基本的File system API的知识,探索html5的本地文件系统API的新特性,希望大家能够喜欢!

介绍

“我们不再需要下载并且安装软件。一个简单的web浏览器和一个可供使用的互联网就足以让我们在任何时间,任何地点,还有任何平台上使用任何web应用程序。”

简单来说,web应用很酷,但是相对于桌面应用来说,它们有比较显著的弱点:它们无法在一个有层次的文件夹结构体即文件系统中互动和组织。 幸运的是,如果我们使用Filesystem API,我们可以做到。这个API帮助我们控制私有的本地文件系统“沙箱(sandbox)",在这里我们可以读和写文件,创建和排列文件夹。虽然在我们写这篇文章的时候,只有Google的Chrome完整的支持Filesystem API,我觉得我们还是有必要学习这个强大并且方便的本地存储特性。

本地文件系统API包含了俩个不同的版本。异步API,对于一般的应用来说非常有用。同步API,特别为web设计。这篇文章中,我们将介绍异步版本的API。

步骤一:开始

首先我们需要通过请求一个LocalFile对象来得到Html5文件系统的访问,使用window.requetFileSystem全局方法:

window.requestFileSystem(type, size, successCallback, opt_errorCallback)

前俩个参数,你指定需要的生命周期类型和文件系统的大小。一个持久性的(Persistent)文件系统非常适合长期保存用户数据。浏览器不会删除,除非用户特意要求。一个临时性(Temporary)的文件系统非常适合web应用来缓存数据,但是在浏览器删除文件系统后任然可以操作。size用来指定字节大小,一般指定有效的最大访问存储大小。

第三个参数是一个回调函数(callback),当用户代理成功的提供了一个文件系统后触发。它的主要参数是一个FileSystem对象。并且我们可以添加一个可选的callback函数,用来在出错的时候调用,或者请求被拒绝的时候。参数是一个FileError对象。虽然这个对象是可选的,最好还是捕捉这些错误,因为很多地方可能会出错。

文件系统得到这些方法依赖于最初包含的document。所有的document或者web应用来自于同一个最初来源共享一个文件系统。两个document或者应用来自于不同的来源完全不同并且不可联系。一个文件系统严格被限制访问一个应用,不能访问另外一个应用保存的数据。同时也对于其它的文件独立。这是一件好事:让文件访问不相干的系统文件资源,例如,操作系统的文件,完全没有必要,也不安全。

我们看看这个例子:

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 5*1024*1024, initFS, errorHandler);
function initFS(fs){
  alert("Welcome to Filesystem! It‘s showtime :)"); // Just to check if everything is OK :)
  // place the functions you will learn bellow here
}
function errorHandler(){
  console.log(‘An error occured‘);
}

这里我们创建而来一个临时的5M文件系统存储。提供了一个成功的callback函数,用阿里操作我们的文件系统。并且添加了一个错误处理,用来处理错误。这里errorhandler()方法非常具有一般性。 如果你想的话,你可以创建一个优化版本,显示给用户更加详细的error信息。

function errorHandler(err){
 var msg = ‘An error occured: ‘;

  switch (err.code) {
    case FileError.NOT_FOUND_ERR:
      msg += ‘File or directory not found‘;
      break;

    case FileError.NOT_READABLE_ERR:
      msg += ‘File or directory not readable‘;
      break;

    case FileError.PATH_EXISTS_ERR:
      msg += ‘File or directory already exists‘;
      break;

    case FileError.TYPE_MISMATCH_ERR:
      msg += ‘Invalid filetype‘;
      break;

    default:
      msg += ‘Unknown Error‘;
      break;
  };

 console.log(msg);
};

这个你得到的文件对象拥有一个name(一个唯一的文件系统名称,由浏览器赋值)并且ROOT属性参考文件系统的ROOT目录。这是一个DirectoryEntry对象,可以嵌套使用。每一个文件目录都可以包含文件,由FileEntry对象标示。DirectoryEntry对象定义使用路径名称得到DirectoryEntry和FileEntry的方法(如果不存在路径名,会创建新的目录)。DirectoryEntry同时定义了createReader()工厂方法用来返回一个DirectoryReader对象用来列出一个文件夹。FileEntry类定义了一个得到File对象的方。你可以使用FileReader对象来读取文件。FileEntry定义了另外一个方法用来返回一个FileWriter对象,你可以将内容写到文件中。

听起来是不是有点儿复杂?通过下面的例子我们会更清楚的理解。

步骤二:处理文件夹

很显然,第一件我们需要做的事就是创建一些目录。虽然ROOT目录已经村存在,你不希望把所有的文件都保存在那里。文件夹使用DirectoryEntry对象来创建。在下面的例子中我们将在ROOT文件夹中创建一个文件夹:Documents

fs.root.getDirectory(‘Documents‘, {create: true}, function(dirEntry) {
  alert(‘You have just created the ‘ + dirEntry.name + ‘ directory.‘);
}, errorHandler);

getDiretory()方法用来读和创建目录。作为第一个参数,你可以传递一个名字或者路径来寻找或者创建。我们设计第二个参数为true,因为我们需要创建一个目录 - 不是读一个已存在的目录。当然我们在最后添加了一个错误的callback方法。

这里我们创建了一个目录,接着我们创建一个子目录。这个方法类似除了一下一点,我们修改第一个参数为”Documents/Music“。很简单是不是,如果你想创建一个子目录,Sky,使用俩个父目录那么怎么做呢? 如果你使用Documents/Music/Nature/Sky作为路径参数,你会得到错误,因为你不能创建一个没有父目录的目录。解决方式是一个一个的创建。但是这样很低效并且麻烦。更好的解决方式:创建一个方法用来自动创建目录:

function createDir(rootDir, folders) {
  rootDir.getDirectory(folders[0], {create: true}, function(dirEntry) {
    if (folders.length) {
      createDir(dirEntry, folders.slice(1));
    }
  }, errorHandler);
};
createDir(fs.root, ‘Documents/Images/Nature/Sky/‘.split(‘/‘));

使用这个小技巧,我们只需要提供完整的路径就能自动为我们创建文件夹。

接下来我们需要检查我们的文件系统。我们创建一个DirectoryReader对象,使用ReadEntries()方法来读取目录中的内容。

fs.root.getDirectory(‘Documents‘, {}, function(dirEntry){<br>
  var dirReader = dirEntry.createReader();
  dirReader.readEntries(function(entries) {<br>
    for(var i = 0; i < entries.length; i++) {
      var entry = entries[i];
      if (entry.isDirectory){
        console.log(‘Directory: ‘ + entry.fullPath);
      }
      else if (entry.isFile){
        console.log(‘File: ‘ + entry.fullPath);
      }
    }

  }, errorHandler);
}, errorHandler);

在以上代码中,isDirectory和isFile属性用来得到不同的输出文件或者文件夹。而且我们使用fullPath属性来得到完整的输入内容,而不是仅仅名字。

这里有两种方式来删除一个DirectoryEntry:remove()和removeRecursively()。第一个删除需要被删除文件夹为空,否则会得到错误。

fs.root.getDirectory(‘Documents/Music‘, {}, function(dirEntry) {
  dirEntry.remove(function(){
    console.log(‘Directory successfully removed.‘);
  }, errorHandler);
}, errorHandler);

If the Music folder has files within it, then you need to use the second method, which recursively deletes the directory and all of its contents.

fs.root.getDirectory(‘Documents/Music‘, {}, function(dirEntry) {
  dirEntry.removeRecursively(function(){
    console.log(‘Directory successufully removed.‘);
  }, errorHandler);
}, errorHandler);

步骤三:处理文件

上面我们介绍了如何创建目录,下面我们介绍如何创建文件。

以下例子在ROOT目录创建了一个空的文件gbin1.txt。

fs.root.getFile(‘gbin1.txt‘, {create: true, exclusive: true}, function(fileEntry) {
  alert(‘A file ‘ + fileEntry.name + ‘ was created successfully.‘);
}, errorHandler);

getFile方法的第一个参数可以是绝对或者相对路径,但是必须是合法的。例如,没有父目录创建一个文件会得到一个错误。第二个参数是一个对象说明,如果文件不存在的话描述功能行为。在这个例子中:create:true表示如果文件不存则创建一个文件,如果存在则抛出错误(exclusive:true)。否则如果create:false,简单取得文件并返回。

fs.root.getFile(‘gbin1.txt‘, {create: false}, function(fileEntry) {
  fileEntry.createWriter(function(fileWriter) {
    window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
    var bb = new BlobBuilder();
    bb.append(‘Filesystem API is awesome!‘);
    fileWriter.write(bb.getBlob(‘text/plain‘));
  }, errorHandler);
}, errorHandler);

以上代码中,我们返回了text.txt文件,创建了FileWriter对象。我们然后通过创建一个新的BlobBuilder对象添加内容并且使用了FileWriter的write()方法。

调用getFile()方法只会返回FileEntry对象。并不返回文件的内容。因此,如果我们想读出文件内容,我们需要使用File对象和FileReader对象。

fs.root.getFile(‘test.txt‘, {}, function(fileEntry) {
  fileEntry.file(function(file) {
    var reader = new FileReader();
    reader.onloadend = function(e) {
      alert(this.result);
    };
    reader.readAsText(file);
  }, errorHandler);
}, errorHandler);

我们已经写入了文件一些内容,但是如果以后添加更多内容呢?为了添加内容到已存在的文件,又需要调用FileWriter。我们可以使用seek()方法重新将writer添加到文件。seek接受字节偏移(byte offset)这个参数,并且设置file writer的位置。

fs.root.getFile(‘test.txt‘, {create: false}, function(fileEntry) {
  fileEntry.createWriter(function(fileWriter) {
    fileWriter.seek(fileWriter.length);
    window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
    var bb = new BlobBuilder();
    bb.append(‘Yes, it is!‘);
    fileWriter.write(bb.getBlob(‘text/plain‘));
  }, errorHandler);
}, errorHandler);

如果需要删除文件,我们调用entry.remove()。一个参数是一个没有参数的回调函数,当文件被成功删除后调用。第二个参数是一个可选的错误回调函数。

fs.root.getFile(‘test.txt‘, {create: false}, function(fileEntry) {
  fileEntry.remove(function() {
    console.log(‘File successufully removed.‘);
  }, errorHandler);
}, errorHandler);

步骤四:处理文件和目录

FileEntry和DirectoryEntry分享同一个API方法来拷贝,移动和重命名。这里有俩个方法你可以使用进行操作:copyTo()和moveTo()。他们都接受同样的参数:

copyTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
moveTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);

第一个参数是目标父目录,即你希望拷贝到的位置。第二个参数是可选的新文件名字,实际只有拷贝到同一个目录才需要。否则得到错误信息。其它俩个参数前面介绍过了。

我们看一个实例,下面我们拷贝gbin1.txt从Root到Documents目录:

function copy(currDir, srcEntry, destDir) {
  currDir.getFile(srcEntry, {}, function(fileEntry) {
    currDir.getDirectory(destDir, {}, function(dirEntry) {
      fileEntry.copyTo(dirEntry);
    }, errorHandler);
  }, errorHandler);
}

copy(fs.root, ‘test.txt‘, ‘Documents/‘);

下面是一个移动gbin1.txt到Document的例子:

function move(currDir, srcEntry, dirName) {
  currDir.getFile(srcEntry, {}, function(fileEntry) {
    currDir.getDirectory(dirName, {}, function(dirEntry) {
      fileEntry.moveTo(dirEntry);
    }, errorHandler);
  }, errorHandler);
}

move(fs.root, ‘gbin1.txt‘, ‘Documents/‘);

下面是重命名的例子:

function rename(currDir, srcEntry, newName) {
  currDir.getFile(srcEntry, {}, function(fileEntry) {
    fileEntry.moveTo(currDir, newName);
  }, errorHandler);
}

rename(fs.root, ‘gbin1.txt‘, ‘gbtags.txt‘);

更多资源

如果你希望了解更多内容,请参考如下:

总结

HTML5的文件系统API是一个强大的技术,提供了很多web应用技术的新的体验。不过实话实说,目前非常新,没有广泛的浏览器支持。但是未来肯定会有很大的改观。或许你愿意成为先行者!Enjoy!

0
时间: 2024-10-11 00:55:50

HTML5之本地文件系统API - File System API的相关文章

KASS分布式文件系统(Kass File System)

KASS分布式文件系统(Kass File System),简称KFS,是开始公司自主研发的分布式文件存储服务平台.KFS系统架构及功能服务类似Hadoop/GFS/DFS,它通过HTTP-WEB为上层应用系统(KASS文档管理系统及各种其他应用系统)提供底层文件存储服务,搭建企业私有云存储服务平台. KFS分布式文件系统提供的核心价值:?     ●    使用多台KFS服务器共同搭建统一的文件逻辑树 ?       ●    支持KFS服务器集群及文件副本实现系统高可靠性 ?       ●

操作系统原理(三)——文件系统(File system)

文件系统(File system) 1. 文件 首先要说文件的定义,文件是进程创建的信息逻辑单元. 由于磁带和光盘的性能较低,磁盘使用的较多.这里讨论文件储存在磁盘中的情况.磁盘可被认为是固定块儿大小的线性序列. 在操作系统看来,文件就是一个个字节流,操作系统不管这个文件的内容(不管它是.mp3音频文件,或者.jpg图片文件,在应用程序看来才有这种区分).文件在操作系统眼中只有3种:普通文件.目录文件.特殊文件. 文件的命名: 在Linux中,文件名大小写敏感:目录分隔符“/”绝对不能出现在文件

Windows -&gt;&gt; Windows下一代文件系统 -- Resilient file system(ReFS)

Comming soon!!! 参考文献: Building the next generation file system for Windows: ReFS ReFS: What you need to know about the Resilient File System (Part 1)

文件系统(File System)

什么是文件系统,引用百科解释: 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统. 文件系统是操作系统核心的组成部分,没有它我们无法完成对文件的增.删.改.查等基本操作 概念 在了解文件系统之前我们需要了解一些基本概念 inode 索引节点 (index node) 我们知道文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata).用户数据,即文件数据块 (data block),数据块是记录文件真实内容的

Oracle ASM 迁移文件系统(File System)

项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前演练,可单独联系进行索取. 文档编号:1-1-1 同机ASM迁移文件系统 原文地址:https://www.cnblogs.com/askscuti/p/11302326.html

HTML5读取本地文件

本文转自:转:http://hushicai.com/2014/03/29/html5-du-qu-ben-di-wen-jian.html感谢大神分享. 常见的语言比如php.shell等,是如何读取文件的呢? 实际上,大多数语言都需要先获取文件句柄,然后调用文件访问接口,打开文件句柄,读取文件! 那么,HTML5是否也是这样的呢? 答案是肯定的! HTML5为我们提供了一种与本地文件系统交互的标准方式:File Api. 该规范主要定义了以下数据结构: File FileList Blob

html5 读取本地文件

尊重原创:http://hushicai.com/2014/03/29/html5-du-qu-ben-di-wen-jian.html HTML5为我们提供了一种与本地文件系统交互的标准方式:File Api. 该规范主要定义了以下数据结构: File FileList Blob html5访问本地文件系统时,需要先获取File对象句柄,获取文件句柄的方式主要有两种:表单输入(选择文件).拖拽. 表单输入: 表单提交是最常用的场景,用户选择文件以后,触发文件选择框的change事件,通过访问文

The Google File System

摘要 我们设计并实现了Google GFS文件系统,一个面向大规模数据密集型应用的.可伸缩的分布式文件系统.GFS虽然运行在廉价的普遍硬件设备上,但是它依然了提供灾难冗余的能力,为大量客户机提供了高性能的服务. 虽然GFS的设计目标与许多传统的分布式文件系统有很多相同之处,但是,我们的设计还是以我们对自己的应用的负载情况和技术环境的分析为基础 的,不管现在还是将来,GFS和早期的分布式文件系统的设想都有明显的不同.所以我们重新审视了传统文件系统在设计上的折衷选择,衍生出了完全不同的设计 思路.

谷歌三大核心技术(一)Google File System中文版

The Google File System中文版 译者:alex 摘要 我们设计并实现了Google GFS文件系统,一个面向大规模数据密集型应用的.可伸缩的分布式文件系统.GFS虽然运行在廉价的普遍硬件设备上,但是它依然了提供灾难冗余的能力,为大量客户机提供了高性能的服务. 虽然GFS的设计目标与许多传统的分布式文件系统有很多相同之处,但是,我们的设计还是以我们对自己的应用的负载情况和技术环境的分析为基础 的,不管现在还是将来,GFS和早期的分布式文件系统的设想都有明显的不同.所以我们重新审