2
votes

I'm very new to Ada and one thing that I find hard to grasp is working with Files in Ada when it comes to append some values in a file. It seems easier for me to do so in C. Anyway, I haven't found good information and I hope someone could help me here.

I declare the following first:

PACKAGE Seq_Float_IO IS NEW Ada.Sequential_IO (Element_Type => Long_Float);
Flo_File : Seq_Long_Float_IO.File_Type;

and then I create a file "bvalues.dat":

Seq_Long_Float_IO.Create(File => Flo_File, Name => "bvalues.dat");

and then to write say a variable named "Largest", I use:

Seq_Long_Float_IO.Write(File => Flo_File, Item => Largest);

I see that every time I run the code the file "bvalues.dat" gets destroyed and new values are written to it as the program runs. This is ok for me. What I'm doing in my code is to find the largest value of some values and store the largest element in the file "bvalues.dat".

Now say I have to repeat the operation with different sets of values IN THE SAME PROGRAM (say with an outer LOOP) and I need to store the largest element of each set of values. Thus I need to be able to append each largest value of every set to the file "bvalues.dat". How to achieve this?

Do I need to close the file "bvalues.dat" each time after writing a largest value and then open it again:

Seq_Long_Float_IO.Open(File => Flo_File, Mode => Append_File, Name => "bvalues.dat");

say after an index in an outer loop gets incremented to take in the next set of values for which the largest element is to be computed and then write as I did above

Seq_Long_Float_IO.Write(File => Flo_File, Item => Largest);   ?

NEW INFO:

I get the error:

40.       Seq_Long_Float_IO.Open(File => Flo_File, Mode => Append_File, Name => "bvalues.dat");
                                                      |
    >>> "Append_File" is not visible
    >>> non-visible declaration at a-sequio.ads:58, instance at line 8
    >>> non-visible declaration at a-textio.ads:56

Thanks a lot...


Test file:

WITH Ada.Text_IO;
WITH Ada.Sequential_IO;

PROCEDURE TestWrite5 IS
   PACKAGE Seq_Float_IO IS NEW Ada.Sequential_IO (Element_Type => Float);
   Flo_File : Seq_Float_IO.File_Type;


BEGIN

   Seq_Float_IO.Open (File => Flo_File, Mode => Seq_Float_IO.Append_File,
   Name =>"bvalues.dat");
   exception
   when Name_Error =>
   Create (File => Flo_File, Mode => Out_File, Name => "bvalues.dat");

END TestWrite5;

On compiling I get:

  1. exception

    1. when Name_Error => |

      "Name_Error" is not visible non-visible declaration at a-sequio.ads:111, instance at line 5 non-visible declaration at a-textio.ads:298 non-visible declaration at a-ioexce.ads:23

    2. Create (File => Flo_File, Mode => Out_File, Name => "bvalues.dat"); |

      "Create" is not visible non-visible declaration at a-sequio.ads:73, instance at line 5 non-visible declaration at a-textio.ads:90

    15.

It doesn't change if I also put Seq_Float_IO.Out_File instead of just Out_File.

1
The compiler error is probably indicating that you need to put the package name in front of that mode. Something like: Seq_Long_Float_IO.Append_File. If its not in that package, try one of the ones the error message suggested (Text_IO, Sequential_IO). - T.E.D.
Thanks again. I get Seq_Long_Float_IO.Append_File is undefined. - yCalleecharan
How to try the others? I have both Text_IO, Sequential_IO in my preamble. I have also tried: Seq_Long_Float_IO_Text_IO.Open. I don't know much what I'm doing here as I'm new to Ada. - yCalleecharan
Mode => Seq_Long_Float_IO.Append_File compiles for me ... - Simon Wright
Thanks. But I didn't succeed, See the piece of code at the bottom of my code. It's a minimal example. What's wrong with it? - yCalleecharan

1 Answers

3
votes

Create, like the name implies, will create a brand new file, even if one already exists.

If the file already exists and you want to append to it, you would use Open.

If you want to open it for appending, but if it doesn't exist create it, the normal idiom is to put the Create call in an exception handler around Open, like so:

begin
   Open (File => Flo_File, Mode => Append_File, Name => "bvalues.dat");
exception
   when Name_Error =>
      Create (File => Flo_File, Mode => Out_File, Name => "bvalues.dat");
end;

From the rest of your text, it looks like you are thinking about storing temp values in a file. I wouldn't do that unless you need persistence for some reason (recovering from crashes, etc). Disk IO is way way way slow. Just keep your temp values in a variable and save the result when you have it.