Differences

This shows you the differences between two versions of the page.

Link to this comparison view

good_text_i_o_practice [2013/01/16 07:40]
sparre Added a Rosetta Code "file I/O" example
good_text_i_o_practice [2013/01/16 08:08] (current)
sparre [POSIX.Memory_Mapping] It is not an _exact_ solution. ;-)
Line 20: Line 20:
    ​File_Name : String ​ := "​read_entire_file.adb";​    ​File_Name : String ​ := "​read_entire_file.adb";​
    ​File_Size : Natural := Natural (Ada.Directories.Size (File_Name));​    ​File_Size : Natural := Natural (Ada.Directories.Size (File_Name));​
- 
    ​subtype File_String ​   is String (1 .. File_Size);    ​subtype File_String ​   is String (1 .. File_Size);
    ​package File_String_IO is new Ada.Direct_IO (File_String);​    ​package File_String_IO is new Ada.Direct_IO (File_String);​
Line 91: Line 90:
 This solution reads from the file one line at a time.  One nice thing about this solution is that you easily can switch it to read from standard input - and possibly anything which your operating system considers a file. This solution reads from the file one line at a time.  One nice thing about this solution is that you easily can switch it to read from standard input - and possibly anything which your operating system considers a file.
  
-<code Ada>with Ada.Text_IO;​ use Ada.Text_IO;​+<code Ada>​with ​Ada.Command_Line, ​Ada.Text_IO;​ use Ada.Command_Line, ​Ada.Text_IO;​
  
 procedure Read_File_Line_By_Line is procedure Read_File_Line_By_Line is
Line 99: Line 98:
    ​Input,​ Output : File_Type;    ​Input,​ Output : File_Type;
 begin begin
-   Open (File => Input, +   begin 
-         ​Mode => In_File, +      ​Open (File => Input, 
-         ​Name => Read_From);​ +            Mode => In_File, 
-   ​Create (File => Output, +            Name => Read_From);​ 
-           ​Mode => Out_File, +   exception 
-           ​Name => Write_To);+      when others => 
 +         ​Put_Line (Standard_Error,​ 
 +                   "​Can not open the file '"​ & Read_From & "'​. Does it exist?"​);​ 
 +         ​Set_Exit_Status (Failure);​ 
 +         ​return;​ 
 +   ​end;​ 
 + 
 +   ​begin 
 +      ​Create (File => Output, 
 +              Mode => Out_File, 
 +              Name => Write_To); 
 +   ​exception 
 +      when others => 
 +         ​Put_Line (Standard_Error,​ 
 +                   "​Can not create a file named '"​ & Write_To & "'​."​);​ 
 +         ​Set_Exit_Status (Failure);​ 
 +         ​return;​ 
 +   ​end;​ 
    loop    loop
       declare       declare
Line 114: Line 131:
    end loop;    end loop;
 exception exception
-   when Name_Error => 
-      Put_Line (Standard_Error,​ 
-                "​Incorrect file name.  Does '"​ & Read_From & "'​ exist?"​);​ 
    when End_Error =>    when End_Error =>
       Close (Input);       Close (Input);
       Close (Output);       Close (Output);
-end Read_File_Line_By_Line;​ +end Read_File_Line_By_Line;</​code>​
-</​code>​+
  
 This solution requires the Ada 2005 standard library to work. This solution requires the Ada 2005 standard library to work.
  
 +Notice how we avoid explicit checks for read access to the input file, creation/​write access to the output file, as well as availablity of more data to process. ​ Even if we put in explicit checks, we would still have to handle the same exceptions, as another application can change the state of the file system in parallel with this application,​ creating a race condition.
 +==== POSIX.Memory_Mapping ====
 +
 +The [[#​posixmemory_mapping|POSIX.Memory_Mapping]] solution for reading an entire file into memory practically solves this task as well.  Still, it has some limitations which may make it irrelevant for some purposes:
 +  * It only works for an actual file (i.e. one stored on a file system). ​ Specifically it doesn'​t work for standard input, pipes and TCP connections.
 +  * It is not line oriented (i.e. you have to parse line-breaks yourself).
 +  * It requires an implementation of the POSIX Ada API (for example FLORIST or WPOSIX).

Navigation