快速上手例:
例1.讀xml
1. var testXML:XML;
2. var file:File = File.documentsDirectory.resolvePath("Mousebomb/test.xml");
3. var fileStream:FileStream = new FileStream();
4. fileStream.open(file, FileMode.READ);
5. testXML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
6. fileStream.close();
例中使用readUTFBytes()方法讀取內容並轉換為XML對象。
例2.寫xml
1. var testXML:XML =<mousebomb><site>www.mousebomb.org</site><blog>www.flashj.cn</blog></mousebomb>;
2. var file:File = File.documentsDirectory.resolvePath("Mousebomb/test.xml");
3. var fileStream:FileStream = new FileStream();
4. fileStream.open(file, FileMode.WRITE);
5. var outputString:String = '<?xml version="1.0" encoding="utf-8"?>/n';
6. outputString += testXML.toXMLString();
7. fileStream.writeUTFBytes(outputString);
8. 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屬性為檔案中的有效位置,比如:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/site.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.open(myFile, FileMode.UPDATE);
4. myFileStream.position = 8;
5. myFileStream.writeUTFBytes("hello");
該例在位置8處寫入UTF編碼的字串“hello”
新開啟的FileStream對象的position值為0,在讀檔案操作前,position的值必最小為0並小於檔案總位元組數。
position的值僅會在以下情況下改變:
1. 直接設定該屬性值
2. 執行讀取操作
3. 執行寫入操作
當執行讀/寫操作時,position的值會立即自增讀/寫的位元組數,再次執行讀/寫操作時會從新的position位置開始:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.open(myFile, FileMode.UPDATE);
4. myFileStream.position = 4000;
5. trace(myFileStream.position); // 4000
6. myFileStream.writeBytes(myByteArray, 0, 200);
7. trace(myFileStream.position); // 4200
position有一個例外:若檔案開啟模式設定為append(追加模式),則position屬性不會隨著寫操作變化。在追加模式下,資料總是往檔案末尾寫,與position無關。
非同步方式開啟檔案,寫資料操作在下一行代碼執行時並沒有結束。這怎麼辦呢?沒關係,你可以按順序的調用多個非同步作業,AIR運行環境會逐個執行:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.openAsync(myFile, FileMode.WRITE);
4. myFileStream.writeUTFBytes("hello");
5. myFileStream.writeUTFBytes("world");
6. myFileStream.addEventListener(Event.CLOSE, closeHandler);
7. myFileStream.close();
8. trace("started.");
9. closeHandler(event:Event):void
10. {
11. trace("finished.");
12. }
該例會輸出:
started.
finished.
你可以在非同步讀寫操作調用後,立即設定position的值,下次讀寫操作將換作從那個位置開始。比如:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.openAsync(myFile, FileMode.UPDATE);
4. myFileStream.position = 4000;
5. trace(myFileStream.position); // 4000
6. myFileStream.writeBytes(myByteArray, 0, 200);
7. myFileStream.position = 300;
8. trace(myFileStream.position); // 300
3. 根據資料格式,選擇合適的讀寫操作
硬碟上的每個檔案都是位元組集合。在AS中,檔案中的資料總是可以描述為ByteArray.比如下面的代碼把檔案資料讀取到bytes這個ByteArray中:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.addEventListener(Event.COMPLETE, completed);
4. myFileStream.openAsync(myFile, FileMode.READ);
5. var bytes:ByteArray = new ByteArray();
6. function completeHandler(event:Event):void
7. {
8. myFileStream.readBytes(bytes, 0, myFileStream.bytesAvailable);
9. }
下面的代碼把資料從bytes這個ByteArray中寫入檔案:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.open(myFile, FileMode.WRITE);
4. myFileStream.writeBytes(bytes, 0, bytes.length);
往往我們並不希望把資料作ByteArray處理,有時候要處理的檔案是特定格式,比如檔案中的資料是字串。因此FileStream類也包含ByteArray以外的資料格式讀寫方法,比如readMultiByte()方法,可將檔案讀取暫存為字串,如下代碼:
1. var myFile:File = File.documentsDirectory.resolvePath("Mousebomb/test.txt");
2. var myFileStream:FileStream = new FileStream();
3. myFileStream.addEventListener(Event.COMPLETE, completed);
4. myFileStream.openAsync(myFile, FileMode.READ);
5. var str:String = "";
6. function completeHandler(event:Event):void
7. {
8. str = myFileStream.readMultiByte(myFileStream.bytesAvailable, "iso-8859-1");
9. }
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檔案操作》結束。所有知識點來自:官方文檔。
(本文若有不當之處,敬請指出。)