我写了一个加密文件的Ada程序。它逐块读取它们以节省目标机器上的内存。不幸的是,Ada的Directories库读取Long_Integer中的文件大小,将读取限制在近2GB的文件中。当尝试读取超过2GB的文件时,程序在运行时失败,导致堆栈溢出错误。
它的文档here是我上面理解的起源。如何将文件大小读入我自己定义的类型?我可以要求像25字节那样将上限增加到100GB。
答案 0 :(得分:5)
我刚刚发布了GCC bug 55119。
在您等待(!)时,以下代码适用于Mac OS X Mountain Lion。在Windows上,它更复杂;见adainclude/adaint.{c,h}
。
Ada规范:
with Ada.Directories;
package Large_Files is
function Size (Name : String) return Ada.Directories.File_Size;
end Large_Files;
和正文(部分从Ada.Directories
复制):
with GNAT.OS_Lib;
with System;
package body Large_Files is
function Size (Name : String) return Ada.Directories.File_Size
is
C_Name : String (1 .. Name'Length + 1);
function C_Size (Name : System.Address) return Long_Long_Integer;
pragma Import (C, C_Size, "large_file_length");
begin
if not GNAT.OS_Lib.Is_Regular_File (Name) then
raise Ada.Directories.Name_Error
with "file """ & Name & """ does not exist";
else
C_Name (1 .. Name'Length) := Name;
C_Name (C_Name'Last) := ASCII.NUL;
return Ada.Directories.File_Size (C_Size (C_Name'Address));
end if;
end Size;
end Large_Files;
和C接口:
/* large_files_interface.c */
#include <sys/stat.h>
long long large_file_length (const char *name)
{
struct stat statbuf;
if (stat(name, &statbuf) != 0) {
return 0;
} else {
return (long long) statbuf.st_size;
}
}
您可能需要在其他Unix系统上使用struct stat64
和stat64()
。
正常编译C接口,然后将-largs large_files_interface.o
添加到gnatmake命令行。
sizeof(long)
是8个字节;因此adaint.c
中的评论具有误导性,Ada.Directories.Size
最多可以返回2 ** 63-1。