AIR文件操作 -转载
AIR文件操作(一):AIR文件基础
?
AIR允许我们开发与文件系统协同工作的应用程序
我们可以使用Adobe? AIR? 文件系统API提供的类访问主机的文件系统。使用这些类,可以访问、管理目录与文件,建立目录与文件,向文件写数据等等。我把与文件系统协同工作的内容总结为AIR文件操作三部分:
AIR文件基础(下文)
使用File对象操作文件和目录
使用FileStream对象读写文件
相关类的语言参考
flash.filesystem.File
flash.filesystem.FileStream
flash.filesystem.FileMode
下面进入AIR文件操作第一部分:
AIR文件基础
AIR提供了让您能用来访问、创建、管理文件与目录的类。这些类被放置在flash.filesystem包中,也就是下面那三个类:
类 描述
File File对象代表一个文件或目录的路径。您可以用file对象建立一个指向文件或目录的指针,以作用于文件或目录。
FileMode FileMode类定义在FileStream类的open()和openAsync()方法中使用的字符串常量参数。
这些方法的FileMode参数确定了文件打开后FileStream对象可用的功能,包括写入、读取、追加和更新。
FileStream FileStream对象打开文件以便读写数据。当创建一个File对象指向一个新的或已存在的文件后,您将该指针传递给FileStream对象,就可以用FileStream来打开并操作文件数据。
File类中的某些方法分别有同步和异步两种版本:
File.copyTo() 和 File.copyToAsync()
File.deleteDirectory() 和File.deleteDirectoryAsync()
File.deleteFile() 和File.deleteFileAsync()
File.getDirectoryListing() 和File.getDirectoryListingAsync()
File.moveTo() 和File.moveToAsync()
File.moveToTrash() 和File.moveToTrashAsync()
同样,FileStream是以同步或异步方式来操作数据,取决于FileStream对象如何打开文件:是调用open()方法还是调用openAsync()方法。
异步版本的处理过程在后台运行,当执行完成或产生错误时触发相应事件。其他代码可以在这些异步操作后台运行的同时执行。使用异步版本操作,你必须设置事件监听,使用File或FileStream对象的addEventListener()方法调用相应函数。
同步版本使您不需要依赖设置事件监听,直接写简单的代码。然而,其他代码无法在同步方法执行时执行,重要的进程(比如显示对象渲染和动画播放)可能被暂停。
?
AIR文件操作(二):使用文件对象操作文件和目录
?
文件对象是啥?
文件对象(File对象)是在文件系统中指向文件或目录的指针。由于安全原因,只在AIR中可用。
文件对象能做啥?
获取特定目录,包括用户目录、用户文档目录、该应用程序启动的目录和程序目录
拷贝文件和目录
移动文件和目录
删除文件和目录(或移至回收站)
列出某目录中的文件和目录
创建临时文件和文件夹
创建目录
读取文件信息
获取文件系统信息
在AIR中,我们用FileStream读写文件的前提就是用File对象来指向文件。
那么文件对象具体怎么玩呢?
功能1、指向目录和文件
File 对象有两个属性都能定义文件路径,它们是nativePath和url。nativePath是在特定平台使用的文件路径(主要就是Windows和 MacOs上的路径表示不同),url则是统一的”file:///c:/Sample%20directory/test.txt”这样的表示方法。
我们来看几个指向目录的实例,其中1-7演示了如何获取特殊目录:
var file:File = File.userDirectory; //指向用户文件夹
var file:File = File.documentsDirectory; //指向用户文档文件夹
var file:File = File.desktopDirectory; //指向桌面
var file:File = File.applicationStorageDirectory; //指向应用程序存储目录
(参见AIR的URL方案)
var dir:File = File.applicationDirectory; //应用程序安装目录
var dir:File = File.getRootDirectories(); //文件系统根目录
还有一招,指向请求启动该应用程序的目录,先空着,以后补上。参考资料见《Capturing command
line arguments》
var file:File = new File();
file.nativePath = "C:\\Mousebomb\";
//(windows平台)指向一个具体的目录,这里使用了nativePath属性,”C:\\Mousebomb\\”只适用windows中。
var file:File = File.userDirectory;
file = file.resolvePath(”Mousebomb”);
//跳转到用户目录下的Mousebomb目录
var urlStr:String = "file:///C:/Mousebomb/";
var file:File = new File()
file.url = urlStr;
//指向c盘下的Mousebomb目录,这里使用了url属性
/*让用户选择目录*/
var file:File = new File();
file.addEventListener(Event.SELECT, dirSelected);
file.browseForDirectory("Select a directory");
function dirSelected(e:Event):void {
trace(file.nativePath);
}
下面看看指向文件的实例:
指向明确的文件地址:
var file:File = File.applicationStorageDirectory;
file = file.resolvePath("Flashj.txt");
使用url属性的例子:
var urlStr:String = "file:///C:/Mousebomb/Flashj.txt";
var file:File = new File()
file.url = urlStr;
当然你也可以直接这样写
var urlStr:String = "file:///C: /Mousebomb/Flashj.txt";
var file:File = new File(urlStr);
//url中的空格会被%20替换
使用nativePath属性:
var file:File = new File();
file.nativePath = "C:/ Mousebomb/Flashj.txt";
或者
var file:File = new File("C:/ Mousebomb/Flashj.txt");
//(Windows下)
通过对话框让用户选择文件
实现这个功能需要认识三个方法:
browseForOpen()
browseForSave()
browseForOpenMultiple()
三 个方法都是异步的,browseForOpen() 和 browseForSave()方法在用户选择文件时会触发select事件,在选择了某文件时,File指向选择的文件。 而browseForOpenMultiple()方法会触发selectMultiple事件,该事件属于FileListEvent型,它的属性中具 有指向所选文件的File对象数组。
例子:
var fileToOpen:File = File.documentsDirectory;
selectTextFile(fileToOpen);
function selectTextFile(root:File):void
{
var txtFilter:FileFilter = new FileFilter("Text", "*.as;*.css;*.html;*.txt;*.xml");
root.browseForOpen("Open", [txtFilter]);
root.addEventListener(Event.SELECT, fileSelected);
}
function fileSelected(event:Event):void
{
trace(fileToOpen.nativePath);
}
功能2、拷贝文件和目录
拷贝文件使用到的方法有copyTo()和copyToAsync(),详见AIR文件基础,前者为同步方法,后者为异步方法。
要拷贝文件,需要创建2个File对象,一个指向原文件,一个指向目标文件。像下面两例:
1.同步拷贝例:
var original:File = File.documentsDirectory.resolvePath("Mousebomb/FlashJ.txt");
var newFile:File = File.resolvePath("Mousebomb/FlashJcn.txt");
original.copyTo(newFile, true);
第二个参数true表示覆盖存在的文件,默认值是false,若设置为false,而拷贝的目标文件已经存在,则AIR会发出IOErrorEvent事件。
2.异步拷贝例:
var original = File.documentsDirectory;
original = original.resolvePath("Mousebomb/FlashJ.txt");
var destination:File = File.documentsDirectory;
destination = destination.resolvePath("FlashJ/FlashJcn.txt");
original.addEventListener(Event.COMPLETE, fileCopyCompleteHandler);
original.addEventListener(IOErrorEvent.IO_ERROR, fileCopyIOErrorEventHandler);
?
?
original.CopyToAsync(destination);
function fileCopyCompleteHandler(event:Event):void {
trace(event.target); // [object File]
}
function fileCopyIOErrorEventHandler(event:IOErrorEvent):void {
trace("I/O Error.");
}
功能3、移动文件和目录
移动文件使用的方法有moveTo()和MoveToAsync(),不仅长相类似,连使用方法都与拷贝文件一样,可以直接参考上文。
功能4、删除文件和目录(或移至回收站)
deleteFile()和deleteFileAsync()负责删除功能,而moveToTrash()和moveToTrashAsync()功能是移至回收站。先创建一个File对象指向某个文件或目录,然后执行四个方法之一,处理异步方法要加事件监听。
var file:File = File.documentsDirectory.resolvePath("DeleteMe.txt");
file.moveToTrash();
功能5、列出某目录中的文件和目录
可以使用getDirectoryListing()方法和getDirectoryListingAsync()方法获取某个目录下文件与子目录的File指针数组。
例如:
var directory:File = File.documentsDirectory;
var contents:Array = directory.getDirectoryListing();
for (var i:uint = 0; i < contents.length; i++)
{
trace(contents[i].name, contents[i].size);
}
本例输出了用户文档目录中的文件名和大小。
若使用异步方法,例如:
var directory:File = File.documentsDirectory;
directory.getDirectoryListingAsync();
directory.addEventListener(FileListEvent.DIRECTORY_LISTING, dirListHandler);
function dirListHandler(event:FileListEvent):void
{
var contents:Array = event.files;
for (var i:uint = 0; i < contents.length; i++)
{
trace(contents[i].name, contents[i].size);
}
}
其中directoryListing事件对象中有个files属性,为目录下内容的File指针数组。
功能6、创建临时文件和文件夹
使用createTempFile()和createTempDirectory()方法可以创建临时文件和文件夹。
var temp:File = File.createTempFile(); //在系统临时文件夹下创建临时文件
createTempFile()方法会自动创建一个唯一的临时文件。
createTempDirectory ()方法会自动创建一个唯一的临时文件夹。
你可以用临时文件来临时存储应用程序回话中的信息。
由于临时文件不会自动删除,所以你可能得让应用程序在关闭前删除它。
功能7、创建目录
使用createDirectory()方法可以创建目录,例如:
var dir:File = File.userDirectory.resolvePath("Mousebomb");
dir.createDirectory();
这个例子在用户文件夹下创建了Mousebomb目录,如果Mousebomb目录存在,则不会作出操作。
功能8、读取文件信息
File类中包含以下属性,提供File对象所指向文件或目录的信息。
属性
?描述
?
creationDate
?创建日期
?
exists
?是否存在
?
extension
?扩展名,若无则为null
?
icon
?该文件的图标对象
?
isDirectory
?是否目录
?
modificationDate
?修改日期
?
name
?文件名(包括扩展名)
?
nativePath
?特定平台使用的文件路径
?
parent
?父级目录,若该File对象就是顶级则此属性为null
?
size
?字节大小
?
url
?统一资源定位符
?
详细参见AIR ActionScript. 3.0 Language Reference for Adobe AIR.
功能9、获取文件系统信息
File类包含一下静态属性,提供有用的文件系统信息(主要是跨平台使用):
属性
?描述
?
File.lineEnding
?系统的行结束符
?
File.separator
?系统的分隔符(Windows下为\ Mac Os为/)
?
File.systemCharset
?系统的默认文件编码,属于系统所使用的字符集
?
顺便插进Capabilities类包含的静态属性:
属性
?描述
?
Capabilities.hasIME
?当前运行的系统是否安装了输入法编辑器
?
Capabilities.language
?当前运行的系统的语言编码
?
Capabilities.os
?当前运行的操作系统
?
参考文献:http://livedocs.adobe.com/air/1/devappsflash/help.html?content=dg_part_6_1.html(文件与数据)
?
AIR文件操作(三):使用FileStream对象读写文件
?
快速上手例:
例1.读xml
var testXML:XML;
var file:File = File.documentsDirectory.resolvePath("Mousebomb/test.xml");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
testXML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
fileStream.close();
例中使用readUTFBytes()方法读取内容并转换为XML对象。
例2.写xml
var testXML:XML =<mousebomb><site>www.mousebomb.org</site><blog>www.flashj.cn</blog></mousebomb>;
var file:File = File.documentsDirectory.resolvePath("Mousebomb/test.xml");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
var outputString:String = '<?xml version="1.0" encoding="utf-8"?>\n';
outputString += testXML.toXMLString();
fileStream.writeUTFBytes(outputString);
fileStream.close();
写XML也一样简单,创建File对象和FileStream对象,使用writeUTFBytes()写入数据。
工作流程
要完成读写文件操作无非就是这几步:
1. 创建File对象指向文件路径
2. 初始化FileStream对象
3. 使用FileStream的open()或openAsync()方法
4. 若使用的是异步的openAsync()方法则需要为FileStream设置事件监听
5. 加入所需的读写数据代码
6. 完成文件操作后执行FileStream的close()方法
使用FileStream要了解的知识
1. FileMode
FileStream的open()和openAsync()方法都包含一个fileMode参数,该参数用于设置:
读取文件能力
写入文件能力
是否总在文件末尾追加数据(写数据时)
文件不存在时如何操作(或文件的父级不存在时)
具体值包括
FileMode值
?描述
?
FileMode.READ
?设置文件打开方式为只读
?
FileMode.WRITE
?设置文件打开方式为写数据。若文件不存在,则创建之;若文件存在,则该文件所有存在数据被删除。
?
FileMode.APPEND
?设置文件打开方式为追加。若文件不存在,则创建之;若存在,则文件所有存在数据不被覆盖,所有写入的数据从文件末尾开始。
?
FileMode.UPDATE
?设置文件打开方式为读写。若文件不存在,则创建之。设置该模式通常用于随机读写访问文件。可以从文件的任意位置读取,写入数据时,只有写入位置的存在字节被覆盖,其他所有字节不受影响。
?
2. position
该属性决定下一个数据读写操作进行的位置。
在读写操作前,设置position属性为文件中的有效位置,比如:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/site.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.UPDATE);
myFileStream.position = 8;
myFileStream.writeUTFBytes("hello");
该例在位置8处写入UTF编码的字符串“hello”
新打开的FileStream对象的position值为0,在读文件操作前,position的值必最小为0并小于文件总字节数。
position的值仅会在以下情况下改变:
直接设置该属性值
执行读取操作
执行写入操作
当执行读/写操作时,position的值会立即自增读/写的字节数,再次执行读/写操作时会从新的position位置开始:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.UPDATE);
myFileStream.position = 4000;
trace(myFileStream.position); // 4000
myFileStream.writeBytes(myByteArray, 0, 200);
trace(myFileStream.position); // 4200
position有一个例外:若文件打开模式设置为append(追加模式),则position属性不会随着写操作变化。在追加模式下,数据总是往文件末尾写,与position无关。
异步方式打开文件,写数据操作在下一行代码执行时并没有结束。这怎么办呢?没关系,你可以按顺序的调用多个异步操作,AIR运行环境会逐个执行:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.openAsync(myFile, FileMode.WRITE);
myFileStream.writeUTFBytes("hello");
myFileStream.writeUTFBytes("world");
myFileStream.addEventListener(Event.CLOSE, closeHandler);
myFileStream.close();
trace("started.");
closeHandler(event:Event):void
{
trace("finished.");
}
该例会输出:
started.
finished.
你可以在异步读写操作调用后,立即设置position的值,下次读写操作将换作从那个位置开始。比如:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.openAsync(myFile, FileMode.UPDATE);
myFileStream.position = 4000;
trace(myFileStream.position); // 4000
myFileStream.writeBytes(myByteArray, 0, 200);
myFileStream.position = 300;
trace(myFileStream.position); // 300
3. 根据数据格式,选择合适的读写操作
硬盘上的每个文件都是字节集合。在AS中,文件中的数据总是可以描述为ByteArray.比如下面的代码把文件数据读取到bytes这个ByteArray中:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(Event.COMPLETE, completed);
myFileStream.openAsync(myFile, FileMode.READ);
var bytes:ByteArray = new ByteArray();
function completeHandler(event:Event):void
{
myFileStream.readBytes(bytes, 0, myFileStream.bytesAvailable);
}
下面的代码把数据从bytes这个ByteArray中写入文件:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.WRITE);
myFileStream.writeBytes(bytes, 0, bytes.length);
往往我们并不希望把数据作ByteArray处理,有时候要处理的文件是特定格式,比如文件中的数据是字符串。因此FileStream类也包含ByteArray以外的数据格式读写方法,比如readMultiByte()方法,可将文件读取暂存为字符串,如下代码:
var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(Event.COMPLETE, completed);
myFileStream.openAsync(myFile, FileMode.READ);
var str:String = "";
function completeHandler(event:Event):void
{
?? str = myFileStream.readMultiByte(myFileStream.bytesAvailable, "iso-8859-1");
}
readMultiByte()的第二个参数(本例中为“iso-8859-1”)指定了ActionScript用来解释的文本格式。ActionScript支持通用字符集编码,具体罗列在http://livedocs.macromedia.com/flex/2/langref/charset-codes.html
FileStream 类还具有readUTFBytes()方法,从读缓存中以UTF-8字符集读取数据。由于UTF8字符集为可变长,读缓存末尾数据并不一定是完整字符,所 以不要在处理progress 事件的方法中使用readUTFBytes()方法(用readMultiByte()读取可变长字符编码也应遵循此项),而应在FileStream的 complete事件发生时读取完整数据集。
同样,有类似的写操作writeMultiByte()和writeUTFBytes(),用来处理字符串对象和文本文件。
readUTF()和writeUTF()方法同样是读写文本数据,不过它们假定文本数据在指定文本数据长度之前,该文本数据是不在标准文本文件里普遍应用的。
有些UTF编码文本文件以一个UTF-BOM(Byte Order Mark)字符开头,像编码格式(如UTF16和UTF32)一样,也声明字节序。
readObject() 和writeObject()方法便于为复杂AS对象存取数据,数据作AMF(ActionScript. Message Format)编码,此格式为ActionScript私有,AIR、Flash Player、Flash Media Server、Flex Data Services以外的程序都没有操作该格式的内建API。
此外还有一些读写操作,像readDouble()和writeDouble()之类的,使用它们需确保所操作文件格式与之对应。
一般的文件结构往往比文本文件要复杂的多。比如mp3文件包含只能被mp3解压解码算法解释的压缩数据格式。其他文件,像图片、数据库、应用程序档案等等都有不同的结构,要想用AS操作它们的数据,得对其结构十分了解。
至此,学习笔记《AIR文件操作》结束。所有知识点来自:官方文档。
(本文若有不当之处,敬请指出。)
参考文献:http://livedocs.adobe.com/air/1/devappsflash/help.html?content=dg_part_6_1.html
http://livedocs.macromedia.com/flex/2/langref/charset-codes.html
http://www.adobe.com/go/learn_air_aslr
文章来自:http://www.flashas.net/html/air/20091005/4593.html