Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
FileAccess
继承: RefCounted < Object
提供用于文件读写操作的方法。
描述
这个类可以用于在用户设备的文件系统中永久存储数据,也可以从中读取数据。适用于存储游戏存档数据或玩家配置文件。
示例:如何读写文件。《数据路径》文档中提到的用户数据文件夹中会存储一个名叫 "save_game.dat" 的文件:
func save_to_file(content):
var file = FileAccess.open("user://save_game.dat", FileAccess.WRITE)
file.store_string(content)
func load_from_file():
var file = FileAccess.open("user://save_game.dat", FileAccess.READ)
var content = file.get_as_text()
return content
public void SaveToFile(string content)
{
using var file = FileAccess.Open("user://save_game.dat", FileAccess.ModeFlags.Write);
file.StoreString(content);
}
public string LoadFromFile()
{
using var file = FileAccess.Open("user://save_game.dat", FileAccess.ModeFlags.Read);
string content = file.GetAsText();
return content;
}
FileAccess 实例拥有自己的文件游标,它是文件中下一次读/写操作将发生的位置(单位为字节)。诸如 get_8()、get_16()、store_8() 和 store_16() 等函数会将文件游标向前移动读/写的字节数。可以使用 seek() 或 seek_end() 将文件游标移动到特定位置,且可以使用 get_position() 获取其位置。
FileAccess 实例被释放时会关闭对应的文件。由于这个类继承自 RefCounted,不再使用实例时会自动触发该行为。可以使用 close() 在此之前显式关闭。在 C# 中引用必须手动释放,可以通过 using 语句或直接调用 Dispose 方法来完成。
注意:要在导出后访问项目资源,建议使用 ResourceLoader 而不是 FileAccess,因为有些文件已被转换为特定于引擎的格式,并且它们的原始源文件可能并不存在于导出的 PCK 包中。如果使用 FileAccess,请确保通过在导入面板中将其导入模式更改为保留文件(按原样导出)来将文件包含在导出中;或者对于没有此选项的文件,请在导出对话框中更改非资源导出筛选器,加上文件的扩展名(例如 *.txt)。
注意:只有当进程“正常”退出时(例如通过单击窗口管理器的关闭按钮或按 Alt + F4),文件才会自动关闭。如果在项目运行时按 F8 停止项目执行,则不会关闭文件,因为游戏进程将被中止。可以通过定期调用 flush() 来解决这个问题。
教程
属性
方法
枚举
enum ModeFlags: 🔗
ModeFlags READ = 1
打开文件进行读取操作。文件游标位于文件的开头。
ModeFlags WRITE = 2
打开文件进行写入操作。如果文件已存在,则将其截断为零长度并清空其内容。否则,将创建该文件。
注意:创建文件必须在已有目录中执行。如果要递归创建文件路径中的目录,见 DirAccess.make_dir_recursive()。
ModeFlags READ_WRITE = 3
打开文件进行读写操作。不会截断文件。文件游标位于文件的开头。
ModeFlags WRITE_READ = 7
打开文件进行读写操作。如果文件已存在,则将其截断为零长度并清除其内容。否则,创建新文件。文件游标位于文件开头。
注意:创建文件必须在已有目录中执行。如果要递归创建文件路径中的目录,见 DirAccess.make_dir_recursive()。
enum CompressionMode: 🔗
CompressionMode COMPRESSION_FASTLZ = 0
使用 FastLZ 压缩方法。
CompressionMode COMPRESSION_DEFLATE = 1
使用 DEFLATE 压缩方法。
CompressionMode COMPRESSION_ZSTD = 2
使用 Zstandard 压缩方法。
CompressionMode COMPRESSION_GZIP = 3
使用 gzip 压缩方法。
CompressionMode COMPRESSION_BROTLI = 4
使用 brotli 压缩方法(仅支持解压缩)。
flags UnixPermissionFlags: 🔗
UnixPermissionFlags UNIX_READ_OWNER = 256
读取所有者比特位。
UnixPermissionFlags UNIX_WRITE_OWNER = 128
写入所有者比特位。
UnixPermissionFlags UNIX_EXECUTE_OWNER = 64
执行所有者比特位。
UnixPermissionFlags UNIX_READ_GROUP = 32
读取组比特位。
UnixPermissionFlags UNIX_WRITE_GROUP = 16
写入组比特位。
UnixPermissionFlags UNIX_EXECUTE_GROUP = 8
执行组比特位。
UnixPermissionFlags UNIX_READ_OTHER = 4
读取其他比特位。
UnixPermissionFlags UNIX_WRITE_OTHER = 2
写入其他比特位。
UnixPermissionFlags UNIX_EXECUTE_OTHER = 1
执行其他比特位。
UnixPermissionFlags UNIX_SET_USER_ID = 2048
在执行位上设置用户 id。
UnixPermissionFlags UNIX_SET_GROUP_ID = 1024
在执行位上设置组 id。
UnixPermissionFlags UNIX_RESTRICTED_DELETE = 512
限制删除(粘性)比特位。
属性说明
如果设为 true,文件将以大端序(big-endian)endianness 进行读取。如果设为 false,文件将以小端序(little-endian)进行读取。如果不确定,保持为 false 即可,因为绝大多数文件都是用小端序写入的。
注意: 每次打开文件时,该属性都会被重置为系统的字节序(在所有受支持的平台上,系统字节序均为小端序)。因此,你必须在打开文件 之后 设置 big_endian,而不是在打开之前。
方法说明
void close() 🔗
关闭当前打开的文件,阻止后续的读写操作。如果要将数据持久化到磁盘而不关闭文件,请使用 flush()。
注意:FileAccess 被释放时会自动关闭,释放发生在离开作用域或被赋值为 null 时。在 C# 中,使用完后必须弃置该引用,可以使用 using 语句或直接调用 Dispose 方法。
FileAccess create_temp(mode_flags: ModeFlags, prefix: String = "", extension: String = "", keep: bool = false) static 🔗
创建临时文件。该文件将在返回的 FileAccess 释放时释放。
如果 prefix 非空,则会将其添加为文件名的前缀,用 - 分隔。
如果 extension 非空,则会将其追加到临时文件名之后。
如果 keep 为 true,则在返回的 FileAccess 释放时不会删除该文件。
如果打开文件失败则返回 null,可以使用 get_open_error() 检查发生的错误。
如果文件光标已经读到了文件末尾,则返回 true。
注意:eof_reached() == false 不能用于检查是否有更多可用数据。要在有更多可用数据时循环,请使用:
while file.get_position() < file.get_length():
# 读取数据
while (file.GetPosition() < file.GetLength())
{
// 读取数据
}
bool file_exists(path: String) static 🔗
如果文件存在于给定路径中,则返回 true。
注意:许多资源类型是导入的(例如纹理或声音文件),它们的源资产不会包含在导出的游戏中,因为只使用导入的版本。有关考虑资源重新映射的替代方法,请参阅 ResourceLoader.exists()。
对于非静态的相对等效项,请使用 DirAccess.file_exists()。
void flush() 🔗
将文件的缓冲区写入磁盘。当关闭文件时,会自动进行刷新。这意味着你不需要在关闭文件前手动调用 flush()。尽管如此,即使项目崩溃而不是正常关闭,调用 flush() 仍可用于确保数据安全。
注意:只有在你真正需要的时候才调用 flush()。否则,它会因不断的磁盘写入而降低性能。
以整数形式返回文件中接下来的 8 位。文件游标前进 1 个字节。请参阅 store_8(),详细了解哪些值可以通过这种方式存储和检索。
以整数形式返回文件中接下来的 16 位。文件游标前进 2 个字节。请参阅 store_16(),以获取有关可以通过这种方式存储和检索哪些值的详细信息。
以整数形式返回文件中接下来的 32 位。文件游标前进 4 个字节。请参阅 store_32(),以获取有关可以通过这种方式存储和检索哪些值的详细信息。
以整数形式返回文件中接下来的 64 位。文件游标前进 8 个字节。请参阅 store_64(),以获取有关可以通过这种方式存储和检索哪些值的详细信息。
int get_access_time(file: String) static 🔗
返回文件 file 的最后访问时间,使用 Unix 时间戳格式,出错时返回 0。这个 Unix 时间戳可以用 Time 单例转换为其他格式。
将整个文件文件内容以 String 形式返回。文本被解释为 UTF-8 编码。该操作会忽略且不影响文件指针。
PackedByteArray get_buffer(length: int) const 🔗
将文件中接下来的 length 个字节作为 PackedByteArray 返回。文件游标前进 length 个字节。
PackedStringArray get_csv_line(delim: String = ",") const 🔗
以 CSV(逗号分隔值)格式返回文件的下一个值。可以传递不同的分隔符 delim,以使用默认 ","(逗号)以外的其他分隔符。这个分隔符必须为一个字符长,且不能是双引号。
文本被解析为 UTF-8 编码。如果文本值包含分隔符,则它们必须用双引号引起来。文本值中的双引号可以通过将它们的出现次数加倍来转义。文件游标前进至行尾的换行符后。
例如,以下 CSV 行是有效的,每行将被正确解析为两个字符串:
Alice,"Hello, Bob!"
Bob,Alice! What a surprise!
Alice,"I thought you'd reply with ""Hello, world""."
请注意第二行如何省略封闭的引号,因为它不包含分隔符。然而它可以很好地使用引号,它只是为了演示目的而没有编写。第三行必须为每个需要被解析为引号而不是文本值的末尾而使用 ""。
将文件中接下来的 64 位作为浮点数返回。文件游标前进 8 个字节。
返回试图执行操作时发生的最后一个错误。请与 Error 中的 ERR_FILE_* 常量比较。
PackedByteArray get_extended_attribute(file: String, attribute_name: String) static 🔗
将名称为 attribute_name 的文件扩展属性读取为字节数组。
注意:该方法已在 Linux、macOS 和 Windows 上实现。
注意:扩展属性的支持取决于文件系统。当文件在不兼容的文件系统之间移动时,属性将会丢失。
注意:在 Linux 上,只能访问“user”命名空间属性,不应包含命名空间前缀。
注意:在 Windows 上,使用备用数据流来存储扩展属性。
String get_extended_attribute_string(file: String, attribute_name: String) static 🔗
将名为 attribute_name 的文件扩展属性读取为 UTF-8 编码的字符串。
注意:该方法已在 Linux、macOS 和 Windows 上实现。
注意:扩展属性的支持取决于文件系统。当文件在不兼容的文件系统之间移动时,属性将会丢失。
注意:在 Linux 上,只能访问“user”命名空间属性,不应包含命名空间前缀。
注意:在 Windows 上,使用备用数据流来存储扩展属性。
PackedStringArray get_extended_attributes_list(file: String) static 🔗
返回文件扩展属性列表。
注意:该方法已在 Linux、macOS 和 Windows 上实现。
注意:扩展属性的支持取决于文件系统。当文件在不兼容的文件系统之间移动时,属性将会丢失。
注意:在 Linux 上,只能访问“user”命名空间属性,不应包含命名空间前缀。
注意:在 Windows 上,使用备用数据流来存储扩展属性。
PackedByteArray get_file_as_bytes(path: String) static 🔗
将整个 path 文件内容作为 PackedByteArray 返回,无需任何解码。
如果打开文件时发生错误,则返回空的 PackedByteArray。你可以使用 get_open_error() 来检查发生的错误。
String get_file_as_string(path: String) static 🔗
将整个 path 文件内容以 String 形式返回。文本被解释为 UTF-8 编码。
如果打开文件时发生错误,则返回空 String。可以使用 get_open_error() 来检查发生的错误。
将文件中接下来的 32 位作为浮点数返回。文件游标前进 4 个字节。
将文件中接下来的 16 位作为半精度浮点数返回。文件游标前进 2 个字节。
如果指定路径的文件的 hidden 属性已设置,则返回 true。
注意:该方法在 iOS、BSD、macOS 和 Windows 上实现。
返回文件的大小,单位为字节。如果是管道,则返回可以从管道中读取的字节数。
以 String 的形式返回文件中的下一行。返回的字符串不包含换行符(\n)和回车符(\r),但是会包含开头和结尾的其他空白字符。文件游标前进至行尾的换行符之后。
文本按照 UTF-8 编码规则进行解析。
String get_md5(path: String) static 🔗
返回一个给定路径文件的 MD5 字符串,如果失败则返回一个空的 String。
int get_modified_time(file: String) static 🔗
返回 file 的最后修改时间,使用 Unix 时间戳格式,出错时返回 0。这个 Unix 时间戳可以用 Time 单例转换为其他格式。
Error get_open_error() static 🔗
返回当前线程中最后一次 open() 调用的结果。
返回文件中的一个以 Pascal 格式保存的 String,即字符串的长度在开头显式存储。见 store_pascal_string()。可能包含换行符。文件游标前进至读取的字节之后。
文本按照 UTF-8 编码规则进行解析。
返回当前打开的文件的路径为 String。
String get_path_absolute() const 🔗
返回当前打开的文件的绝对路径为 String。
返回文件游标的位置,单位为字节,相对于文件的开头。文件读写游标由 seek() 和 seek_end() 设置,读写操作会导致游标前进。
bool get_read_only_attribute(file: String) static 🔗
如果指定路径的文件的 read only 属性已设置,则返回 true。
注意:此方法在 iOS、BSD、macOS 和 Windows 上实现。
返回文件中后续数据构成的一个浮点数。文件游标前进 4 个或 8 个字节,取决于保存文件的 Godot 构建所使用的精度。
如果保存文件的是使用 precision=single 编译的 Godot 构建(默认),则会从文件中读取 32 位。否则如果是使用 precision=double 编译的,那么读取的就是 64 位。
String get_sha256(path: String) static 🔗
返回一个表示给定路径下文件的 SHA-256 String,失败时返回一个空的 String。
int get_size(file: String) static 🔗
返回给定路径的文件大小,单位为字节,出错时为 -1。
BitField[UnixPermissionFlags] get_unix_permissions(file: String) static 🔗
返回给定路径的文件的 UNIX 权限。
注意:该方法在 iOS、Linux/BSD 和 macOS 上实现。
Variant get_var(allow_objects: bool = false) const 🔗
返回文件中的下一个 Variant 值。如果 allow_objects 为 true,则允许解码对象。这会使文件光标前进读取的字节数。
在内部,这使用与 @GlobalScope.bytes_to_var() 方法相同的解码机制,如在二进制序列化 API 文档中所述。
警告:反序列化得到的对象可能包含被执行的代码。如果序列化的对象来自不受信任的来源,请不要使用这个选项,以避免潜在的安全威胁,如远程代码执行。
如果文件当前被打开,返回 true。
FileAccess open(path: String, flags: ModeFlags) static 🔗
创建一个新的 FileAccess 对象,会根据标志来确定以写入还是读取模式打开文件。
如果打开文件失败,则返回 null 。你可以使用 get_open_error() 来检查发生的错误。
FileAccess open_compressed(path: String, mode_flags: ModeFlags, compression_mode: CompressionMode = 0) static 🔗
创建一个新的 FileAccess 对象,并打开一个压缩文件以进行读取或写入。
注意:open_compressed() 只能读取 Godot 保存的文件,不能读取第三方压缩格式。有关解决方法,请参阅 GitHub 问题 #28999。
如果打开文件失败,则返回 null。可以使用 get_open_error() 来检查发生的错误。
FileAccess open_encrypted(path: String, mode_flags: ModeFlags, key: PackedByteArray, iv: PackedByteArray = PackedByteArray()) static 🔗
创建一个新的 FileAccess 对象,并以写入或读取模式打开一个加密文件。需要传入一个二进制密钥来加密/解密它。
注意:提供的密钥必须是 32 字节长。
如果打开文件失败,则返回 null。可以使用 get_open_error() 来检查发生的错误。
FileAccess open_encrypted_with_pass(path: String, mode_flags: ModeFlags, pass: String) static 🔗
创建一个新的 FileAccess 对象,以写或读的模式打开一个加密文件。你需要传递一个密码来加密/解密它。
如果打开文件失败,则返回 null 。你可以使用 get_open_error() 来检查发生的错误。
Error remove_extended_attribute(file: String, attribute_name: String) static 🔗
移除名为 attribute_name 的文件扩展属性。
注意:该方法已在 Linux、macOS 和 Windows 上实现。
注意:扩展属性的支持取决于文件系统。当文件在不兼容的文件系统之间移动时,属性将会丢失。
注意:在 Linux 上,只能访问“user”命名空间属性,不应包含命名空间前缀。
注意:在 Windows 上,使用备用数据流来存储扩展属性。
将文件大小修改为指定长度。文件必须使用允许写操作的模式打开。如果扩展了文件,则会追加 NUL 字符。如果截断了文件,则会丢弃从文件末尾到文件原长度之间的所有数据。
将文件游标设置到指定位置,单位为字节,相对于文件的开头。这将改变 get_position() 的返回值。
void seek_end(position: int = 0) 🔗
将文件光标设置到距离文件末尾指定字节数的位置。这会改变 get_position() 返回的值。
注意: 这是一个偏移量,所以你应该使用负数,否则文件光标会移动到文件末尾之外。
Error set_extended_attribute(file: String, attribute_name: String, data: PackedByteArray) static 🔗
将名为 attribute_name 的文件扩展属性写入为字节数组。
注意:该方法已在 Linux、macOS 和 Windows 上实现。
注意:扩展属性的支持取决于文件系统。当文件在不兼容的文件系统之间移动时,属性将会丢失。
注意:在 Linux 上,只能访问“user”命名空间属性,不应包含命名空间前缀。
注意:在 Windows 上,使用备用数据流来存储扩展属性。
Error set_extended_attribute_string(file: String, attribute_name: String, data: String) static 🔗
将名为 attribute_name 的文件扩展属性写入为 UTF-8 编码的字符串。
注意:该方法已在 Linux、macOS 和 Windows 上实现。
注意:扩展属性的支持取决于文件系统。当文件在不兼容的文件系统之间移动时,属性将会丢失。
注意:在 Linux 上,只能访问“user”命名空间属性,不应包含命名空间前缀。
注意:在 Windows 上,使用备用数据流来存储扩展属性。
设置文件 hidden 属性。
注意:该方法在 iOS、BSD、macOS 和 Windows 上实现。
Error set_read_only_attribute(file: String, ro: bool) static 🔗
设置文件 read only 属性。
注意:该方法在 iOS、BSD、macOS 和 Windows 上实现。
Error set_unix_permissions(file: String, permissions: BitField[UnixPermissionFlags]) static 🔗
设置文件的 UNIX 权限。
注意:该方法在 iOS、Linux/BSD 和 macOS 上实现。
将一个整数以 8 位形式存储在文件中。文件游标前进 1 个字节。如果操作成功则返回 true。
注意:value 应该位于 [0, 255] 的区间内。任何其他的值都会溢出并环绕。
注意:出错时,文件位置标识符的取值不确定。
要存储有符号的整数,请使用 store_64(),或者手动转换(见 store_16() 的例子)。
将一个整数以 16 位形式存储到文件中。文件游标前进 2 个字节。如果操作成功则返回 true。
注意:value 应该位于 [0, 2^16 - 1] 区间内。任何其他的值都会溢出并进行环绕。
注意:出错时,文件位置标识符的取值不确定。
要存储有符号的整数,请使用 store_64() 或者从区间 [-2^15, 2^15 - 1] 中存储一个有符号的整数(即保留一位作为符号),在读取时手动计算其符号。例如:
const MAX_15B = 1 << 15
const MAX_16B = 1 << 16
func unsigned16_to_signed(unsigned):
return (unsigned + MAX_15B) % MAX_16B - MAX_15B
func _ready():
var f = FileAccess.open("user://file.dat", FileAccess.WRITE_READ)
f.store_16(-42) # 发生环绕,存储 65494 (2^16 - 42)。
f.store_16(121) # 在范围内,存储 121。
f.seek(0) # 回到开头,读取存储的值。
var read1 = f.get_16() # 65494
var read2 = f.get_16() # 121
var converted1 = unsigned16_to_signed(read1) # -42
var converted2 = unsigned16_to_signed(read2) # 121
public override void _Ready()
{
using var f = FileAccess.Open("user://file.dat", FileAccess.ModeFlags.WriteRead);
f.Store16(unchecked((ushort)-42)); // 发生环绕,存储 65494 (2^16 - 42)。
f.Store16(121); // 在范围内,存储 121。
f.Seek(0); // 回到开头,读取存储的值。
ushort read1 = f.Get16(); // 65494
ushort read2 = f.Get16(); // 121
short converted1 = (short)read1; // -42
short converted2 = (short)read2; // 121
}
将一个整数以 32 位形式存储到文件中。文件游标前进 4 个字节。如果操作成功则返回 true。
注意:value 应该位于 [0, 2^32 - 1] 区间内。任何其他的值都会溢出并环绕。
注意:出错时,文件位置标识符的取值不确定。
要存储有符号的整数,请使用 store_64(),或者手动转换(见 store_16() 的例子)。
将一个整数以 64 位形式存储到文件中。文件游标前进 8 个字节。如果操作成功则返回 true。
注意:value 必须位于 [-2^63, 2^63 - 1] 的区间内(即有效的 int 值)。
注意:出错时,文件位置标识符的取值不确定。
bool store_buffer(buffer: PackedByteArray) 🔗
将给定的字节数组存储在文件中。文件游标前进写入的字节数。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_csv_line(values: PackedStringArray, delim: String = ",") 🔗
将给定的 PackedStringArray 作为 CSV(逗号分隔值)格式的行存储在文件中。你可以传递不同的分隔符 delim 以使用默认 ","(逗号)以外的其他分隔符。此分隔符的长度必须为一个字符。
将使用 UTF-8 编码文本。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_double(value: float) 🔗
将一个浮点数以 64 位的形式存储到文件中。文件游标前进 8 个字节。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_float(value: float) 🔗
将一个浮点数以 32 位的形式存储到文件中。文件游标前进 4 个字节。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_half(value: float) 🔗
将一个半精度浮点数以 16 位的形式存储到文件中。文件游标前进 2 个字节。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_line(line: String) 🔗
将 line 存储到文件中,后跟一个换行符(\n),文本使用 UTF-8 编码。文件游标前进该行长度,至换行符后。写入的字节数取决于 UTF-8 编码后的字节,可能与 String.length() 不同,后者计算的是 UTF-32 码位的数量。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_pascal_string(string: String) 🔗
将给定的 String 作为一行存储到文件中,使用 Pascal 格式(即同时存储字符串的长度)。文本使用 UTF-8 编码。文件游标的前进量为写入的字节数,取决于 UTF-8 编码后的字节,可能与 String.length() 不同,后者计算的是 UTF-32 码位的数量。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_real(value: float) 🔗
将一个浮点数存储到文件中。文件游标前进 4 个或 8 个字节,取决于当前 Godot 构建所使用的精度。
如果所用的 Godot 构建在编译时使用了 precision=single 选项(默认),则该方法保存的是 32 位 float。否则如果编译时使用了 precision=double 选项,则保存的是 64 位 float。如果操作成功则返回 true。
注意:出错时,文件位置标识符的取值不确定。
bool store_string(string: String) 🔗
将 string 存储到文件中,不带换行符(\n),文本使用 UTF-8 编码。文件游标的前进量为 UTF-8 编码后的字节数,可能与 String.length() 不同,后者计算的是 UTF-32 码位的数量。如果操作成功则返回 true。
注意:该方法适用于写入文本文件。字符串以 UTF-8 编码的缓冲区形式存储,不带字符串长度,不以零结尾,加载并非易事。如果你想要在二进制文件中存储便于读取的字符串,请考虑改用 store_pascal_string()。从文本文件中读取字符串可以使用 get_buffer(length).get_string_from_utf8()(前提是知道长度)或 get_as_text()。
注意:出错时,文件位置标识符的取值不确定。
bool store_var(value: Variant, full_objects: bool = false) 🔗
将任意 Variant 值存储到文件中。如果 full_objects 为 true,则允许将对象进行编码(可能包含代码)。文件游标的前进量为写入的字节数。如果操作成功则返回 true。
内部使用的编码机制与 @GlobalScope.var_to_bytes() 方法相同,见《二进制序列化 API 》文档。
注意:不是所有属性都会包含在内。只会对设置了 @GlobalScope.PROPERTY_USAGE_STORAGE 标志的属性进行序列化。在你的类中覆盖 Object._get_property_list() 可以为属性添加新的用法标志。你也可以调用 Object._get_property_list() 查看属性用法的设置情况。可能的用法标志见 PropertyUsageFlags。
注意:出错时,文件位置标识符的取值不确定。