如何在Ada中读取大型文件?

Dak*_*est 4 ada filesize

我写了一个加密文件的Ada程序.它逐块读取它们以节省目标机器上的内存.不幸的是,Ada的Directories库读取Long_Integer中的文件大小,将读取限制在近2GB的文件中.尝试读取超过2GB的文件时,程序在运行时失败,导致堆栈溢出错误.

它的文档这里是我的上述认识的来源.如何将文件大小读入我自己定义的类型?我可以要求一个像25字节的东西来增加100GB的上限.

Sim*_*ght 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;
Run Code Online (Sandbox Code Playgroud)

和身体(部分复制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;
Run Code Online (Sandbox Code Playgroud)

和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;
  }
}
Run Code Online (Sandbox Code Playgroud)

您可能需要使用struct stat64stat64()其他Unix系统.

正常编译C接口,然后添加-largs large_files_interface.o到您的gnatmake命令行.

编辑:在Mac OS X(和Debian)上,它们是x86_64机器,sizeof(long)是8个字节; 所以评论adaint.c是误导性的,Ada.Directories.Size最多可以返回2**63-1.