6、Libgdx文件处理

(官网:www.libgdx.cn

简介


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 Android HTML5 iOS
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();
www.libgdx.cn版权所有,如需转载,注明出处)

上一篇:项目cookie优化之cookie数量限制和多页面共享污染数据问题


下一篇:C++中数据共享的实现机制