How to read large files in Ada?

I wrote an Ada program that encrypts files. It reads them block by block to save memory on the target machine. Unfortunately, the Ada directory library reads files in Long_Integer, limiting the reading to almost 2 GB of files. When you try to read files larger than 2 GB, the program does not work at run time, receiving an error.

The documentation for him here is the source of my understanding above. How can I read a file into a type that I define myself? One that I can do by requiring something like 25 bytes to increase the cap to 100 GB.

+4
source share
1 answer

I just posted a GCC bug 55119 on this.

While you wait (!), The code below works on Mac OS X Mountain Lion. On Windows, this is more complicated; see adainclude/adaint.{c,h} .

Ada Specification:

 with Ada.Directories; package Large_Files is function Size (Name : String) return Ada.Directories.File_Size; end Large_Files; 

and body (copied partially from 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; 

and C interface:

 /* 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; } } 

You may need to use struct stat64 and stat64() on other Unix systems.

Compile the C interface as usual, then add -largs large_files_interface.o to your gnatmake command line.

EDIT: on Mac OS X (and Debian), which are x86_64 machines, sizeof(long) - 8 bytes; therefore, the comment in adaint.c is misleading, and Ada.Directories.Size can return up to 2 ** 63-1.

+5
source

Source: https://habr.com/ru/post/1442637/


All Articles