簡介
Libgdx應用運作在四個不同的平台中:桌面系統(Windows,Linux,Mac OS X等等),Android,iOS和JavaScript或者WebGL。每個平台處理檔案I/O有一些不同。
Libgdx檔案子產品提供了以下操作檔案功能:
從檔案中讀取
寫入到檔案
複制檔案
移動檔案
删除檔案
周遊檔案和目錄
檢測檔案或目錄是否存在
在我們深入了解Libgdx的檔案子產品之前,首先了解一下各個系統的差異。
各個平台檔案系統
這裡我們簡單的了解一下Libgdx支援的各個平台的檔案系統。
Desktop(Windows,Linux,Mac OS X等等)
在桌面系統中,檔案系統是一個大塊的記憶體。檔案可以通過目前的工作目錄或者絕對路徑被引用。可以忽略相關權限,檔案和目錄通常可以被所有的程式讀寫。
Android
在Android中情況有一點複雜。檔案可以通過資源或者assets的形式存儲在應用的APK中。這些檔案是隻讀的。Libgdx僅僅使用assets機制,assets提供了對原始檔案的比特流的通路并且最接近傳統的檔案系統。資源檔案适用于Android的正常的應用,但是在用到遊戲當中時會遇到很多問題。Android在載入時可以控制資源檔案,比如自動調整圖檔大小。
Assets存儲在Android項目的assets目錄下并且将被打包到APK中,其它的應用不可以通路這些檔案。
檔案也能儲存到内部存儲中,可以進行讀寫。每一個安裝的應用都有一個獨立的目錄,這個目錄隻有這個應用才有通路權限。可以将這種存儲視為應用的私有存儲空間。
檔案也可以存儲到外存中,像SD卡。外存并不是所有的時候都可用。檔案存儲的目錄不穩定,在使用外存之前,你需要在AndroidManifest.xml中添加相關權限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
iOS
在iOS中所有檔案類型暫不可用。
Javascript或WebGL
一個原始的Javascript或WebGL應用沒有一個傳統的檔案系統的概念。像圖檔等資源通過URL來實作。現在浏覽器統一支援本地存儲,這和傳統的檔案系統基本類似。
Libgdx提供給你對于隻讀檔案系統的一種抽象。
檔案(存儲)類型
在Libgdx中的檔案代表了一個FileHandle類的執行個體,一個FileHandle有一個指定了檔案存儲位置的類型。
類型
描述
Desktop
HTML5
Classpath
隻讀
是的
Internal
Local
讀寫
External
Absolute
相對路徑和classpath檔案通常是在工具中使用,對遊戲來說是可以忽略的,你能使用的三種類型如下:
Internal檔案:所有的assets(圖檔,音頻檔案等)都是internal檔案。如果你使用Setup UI(也就是Gdx-setup),隻需要将他們放置到Android項目的assets檔案夾。
Local檔案:如果你需要寫入到檔案中某些資料,比如遊戲狀态,使用local檔案。對你的應用來說是私有的。如果是存儲key或者之,可以使用Preferences。
External檔案:如果需要寫入大的檔案,比如截屏,或者從網絡上下載下傳檔案,需要使用external存儲。注意的是,external可以被使用者删除。
檢測存儲和路徑的可用性
不同的存儲類型可能在不同的平台不能使用。可以通過檔案子產品來判斷是否可用。
boolean isExtAvailable = Gdx.files.isExternalStorageAvailable();
boolean isLocAvailable = Gdx.files.isLocalStorageAvailable();
同樣可以查詢external和local存儲的根目錄:
String extRoot = Gdx.files.getExternalStoragePath();
String locRoot = Gdx.files.getLocalStoragePath();
擷取檔案處理
FileHandle可以通過檔案子產品擷取上述的類型,接下來的代碼是擷取internal的myfile.txt檔案。
FileHandle handle = Gdx.files.internal("data/myfile.txt");
列出和檢查檔案屬性
有些時候檢測特定的檔案是否存在或者列出目前目錄的檔案是必要的。FileHandle提供了簡潔的方法來實作。
以下是一個執行個體,檢測檔案是否存在,是否是檔案夾。
boolean exists = Gdx.files.external("doitexist.txt").exists();
boolean isDirectory = Gdx.files.external("test/").isDirectory();
列出指定目錄的所有檔案或檔案夾:
FileHandle[] files = Gdx.files.local("mylocaldir/").list();
for(FileHandle file: files) {
// 在這裡做你想要做的事情。
}
警告:如果沒指明檔案夾,list将為空。
注意:internal目錄在Desktop下不支援。
我們可以查詢檔案的父檔案夾:
FileHandle parent = Gdx.files.internal("data/graphics/myimage.png").parent();
還有更多的功能,可以查閱javadoc文檔。
注意:這些方法大部分不支援HTML5。
錯誤處理
有些時候,通過FileHandle操作檔案可能導緻失敗。我們可以使用RuntimeExceptions來捕獲異常。在90%的情況下,我們通路的檔案是已知存在的。
讀取一個檔案
擷取FileHandle之後,我們可以載入檔案内容,或者讀取内容。
FileHandle file = Gdx.files.internal("myfile.txt");
String text = file.readString();
如果你是讀取二進制資料,可以通過以下方式。
FileHandle file = Gdx.files.internal("myblob.bin");
byte[] bytes = file.readBytes();
還有更多的方式,可以查閱javadocs。
跟讀取檔案相同。需要注意的是,隻有local,external和absolute檔案類型支援寫入。
FileHandle file = Gdx.files.local("myfile.txt");
file.writeString("My god, it's full of stars", false);
删除,複制,重命名和移動檔案或檔案夾
這些操作同樣是在local,external和absolute檔案類型下操作。
FileHandle from = Gdx.files.internal("myresource.txt");
from.copyTo(Gdx.files.external("myexternalcopy.txt");
Gdx.files.external("myexternalcopy.txt").rename("mycopy.txt");
Gdx.files.external("mycopy.txt").moveTo(Gdx.files.local("mylocalcopy.txt"));
Gdx.files.local("mylocalcopy.txt").delete();