【发布时间】:2012-10-28 21:00:49
【问题描述】:
我编写了一个加密文件的 Ada 程序。它逐块读取它们以节省目标机器上的内存。不幸的是,Ada 的目录库读取 Long_Integer 中的文件大小,将读取限制为近 2GB 文件。尝试读取超过 2GB 的文件时,程序在运行时失败,出现堆栈溢出错误。
它的文档here 是我上面理解的起源。如何将文件大小读入我自己定义的类型?我可以将上限增加到 100GB,需要 25 个字节。
【问题讨论】:
-
您不需要 25 个字节来保存该大小的数字; 8 个字节(64 位)绰绰有余。
-
Ada 标准的定义是
type File_Size is range 0 ..*implementation-defined*;。 GNAT,至少在我拥有的版本中,有File_Size'Last = 9223372036854775807。你用的是什么编译器?你确定这是堆栈溢出吗?这不是我所期望的错误。试试Ada.Text_IO.Put_Line(Ada.Directories.File_Size'Image(Ada.Directories.File_Size'Last)); -
查看 GNAT GPL 2012 的源代码,
adaint.c在__gnat_stat_to_attr()中说“st_size 可能是 32 位,或 64 位转换为长整数。我们不返回有用的值无论哪种情况,文件都大于 2 GB。”它的实际意思是“我们不会费心检查操作系统报告的文件大小是否适合 32 位结果,我们只是分配它。”在 Mac OS X 上,这会丢弃 64 位结果的前 32 位,并可能给出明显的否定结果。我认为您可能必须通过stat(2)(或您的操作系统上的等效项)读取文件大小。 -
@SimonWright:你是对的;在我的系统上,
File_Size是 64 位,但Size()函数的结果会丢弃除低位 32 位之外的所有位。这是 GNAT 中的一个错误。