Writing Files in Ada

Here’s the translation of the Go code to Ada, formatted in Markdown suitable for Hugo:

Writing files in Ada follows similar patterns to the ones we saw earlier for reading.

with Ada.Text_IO;
with Ada.Streams.Stream_IO;
use Ada.Text_IO;
use Ada.Streams.Stream_IO;

procedure Write_Files is
   File : File_Type;
   S : Stream_Access;

   procedure Check (Condition : Boolean) is
   begin
      if not Condition then
         raise Program_Error with "An error occurred";
      end if;
   end Check;

begin
   -- To start, here's how to dump a string (or just bytes) into a file.
   declare
      Content : String := "hello" & ASCII.LF & "ada" & ASCII.LF;
   begin
      Put_Line (Content, "/tmp/dat1");
   end;

   -- For more granular writes, open a file for writing.
   Create (File, Out_File, "/tmp/dat2");

   -- It's idiomatic to close the file immediately after opening it.
   -- Ada doesn't have a 'defer' keyword, so we'll use a block statement.
   begin
      S := Stream (File);

      -- You can write byte arrays as you'd expect.
      declare
         D2 : constant array (1 .. 5) of Character := ('s', 'o', 'm', 'e', ASCII.LF);
      begin
         Character'Write (S, D2(1));
         Character'Write (S, D2(2));
         Character'Write (S, D2(3));
         Character'Write (S, D2(4));
         Character'Write (S, D2(5));
         Put_Line ("wrote 5 bytes");
      end;

      -- A String_Write is also available.
      String'Write (S, "writes" & ASCII.LF);
      Put_Line ("wrote 7 bytes");

      -- Ada doesn't have an explicit 'Sync' operation, but closing the file ensures all data is written.

      -- Ada.Text_IO provides buffered writers in addition to the buffered readers we saw earlier.
      Put_Line (File, "buffered");
      Put_Line ("wrote 9 bytes");

      -- Use Close to ensure all buffered operations have been applied to the underlying writer.
      Close (File);
   exception
      when others =>
         if Is_Open (File) then
            Close (File);
         end if;
         raise;
   end;
end Write_Files;

Try running the file-writing code:

$ gnatmake write_files.adb
$ ./write_files
wrote 5 bytes
wrote 7 bytes
wrote 9 bytes

Then check the contents of the written files:

$ cat /tmp/dat1
hello
ada
$ cat /tmp/dat2
some
writes
buffered

Next, we’ll look at applying some of the file I/O ideas we’ve just seen to the standard input and output streams.