Append file operation in Ada - file

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:
exception
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
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.

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.

Related

JavaScript React, I can't read text file and assign a name

I need to compare 2 company names, one is from a text file, the other from databases. I import a licence in txt file and if the names are different, a notification on page will pop up asking if I want to rename it (new name will be saved in database).
In JavaScript React, I have to write code that can read a text file, specifically one line from it. This line contains the name of the company that I need to compare with the second name which is in the database.
const handleDispalyDialogButtonClick = () => {
if (nametxt! == namedatabase) {
setDisplayDialog(true)
}
handleImportButtonClick();
};
nametxt is to be the name of the company in the text file. This name needs to be imported somehow and assigned to nametxt.
[license]
lic_base=xxxx
lic_nip=xxxx
PC_Nazwa1=name of the company1
PC_Nazwa2=name of the company2
PC_Nazwa3=name of the company3
For example it's like Car=BMW.
Does anyone have a solution how to make a code which gonna import information, and assign it?
You need to put the file you want in your public folder and just fetch it:
fetch('/path/to/the/file').then((response) => response.text())
.then((data) => {
// read file lines here
const fileLines = data.split('\n')
// find the value you are looking for and compare it to the value you get from the database
}
Also, the screenshot you shared looks like a TOML file, you might want to parse that with TOML Parser to make things easier.
For the value on the database, you cannot directly interact with a database from your code. You need to have an extra layer like an API and request the data from there.

Perl Config::IniFiles - how do I create the ini file 'if not exists'? WriteConfig method fails with error

I want to use a number of .ini files to store sets of values to pick up later, when I re-run the script (after a reboot, e.g.). I am trying to write my code such that it will first check to see if the specific .ini file exists, and if so, read in the values, but if not, then create it (the script will subsequently proceed to store values in it).
if (-f '/path/to/file.ini') { # if file exists
# read file into object
my $ini = Config::IniFiles->new(-file => '/path/to/file.ini',
-nomultiline => 1, -fallback => 'parameters', -commentchar => ';'
);
} else {
# create first instance of ini file
WriteConfig('/path/to/file.ini');
}
Obviously I don't understand how to use Config::InFiles because it keeps failing on WriteConfig('/path/to/file.ini');.
Can I create a file with this module, or do I have to do it another way?
WriteConfig is an object method and would be called as $ini->WriteConfig(...);
This creates a new file:
use warnings;
use strict;
use Config::IniFiles;
my $ini = Config::IniFiles->new();
$ini->AddSection('section1');
$ini->newval('section1', 'param1', 123);
$ini->WriteConfig('./file.ini');
File file.ini now contains:
[section1]
param1=123

How to make the onremovefile on Filepond?

I want to get the file of which I am deleting on Filepond. However when I use onremovefile={(file) => this.handleRemove(file)}, the file returns to null. What am I doing wrong?
Found the solution! The first parameter is a possible error response and the second one is the file item. Thus it's actually onremovefile={(errRes, file) => this.handleRemove(errRes, file)}

How to run batch file with parameter from DBMS_SCHEDULER chain job

Case:
I have windows batch file start.bat which do some operations using extr_mode parameter passed from the outside:
rem settings
set extr_mode=%1
rem the rest of the script
When I'm calling it from cmd using i.e.: start.bat DAILY it works fine and parameter is passed.
Now I'm trying to call this batch file under DBMS_SCHEDULER chain job's program:
begin
sys.dbms_scheduler.create_program(program_name => 'OUT_BAT',
program_type => 'EXECUTABLE',
program_action => 'C:\Job\start.bat DAILY',
number_of_arguments => 0,
enabled => true,
comments => 'Out batch file');
end;
/
this program without parameter (program_action => 'C:\Job\start.bat') runs ok, but when I'm adding parameter job is failing.
I mean, I'm checking dba_scheduler_job_run_details and for this step STATUS = SUCCEEDED, but in ADDITIONAL_INFO there is:
CHAIN_LOG_ID="490364", STEP_NAME="OUT", STANDARD_ERROR="The system cannot find the path specified.
The system cannot find the path specified."
I didn't find any specific answer for my question, so is it possible to run batch file with parameter from DBMS_SCHEDULER chain job?
Frankly, I've no idea about dbms-scheduler.
Naturally, batch can provide a solution, which may or may not be suitable.
Create a new batch called startDAILY.bat containing simply this:
C:\Job\start.bat DAILY
and change your setting
program_action => 'C:\Job\startDAILY.bat'
I'm suspicious about your code line stating
number_of_arguments => 0,
I'd suspect that you may be able to change this to say, number_of_arguments => 1,
and then well - perhaps the dbms-scheduler manual may give a hint about how to supply DAILY as the first argument so that you can use your original code.
Oh BTW - using start as a batch name is not a good idea as START is a batch keyword.
Problem solved - thanks for tip #Magoo,
I needed to create program first:
sys.dbms_scheduler.create_program(program_name => 'OUT_BAT',
program_type => 'EXECUTABLE',
program_action => 'C:\OUT_start.bat',
number_of_arguments => 1,
enabled => false,
comments => 'Out batch file');
then define program argument and enable program:
sys.dbms_scheduler.define_program_argument(program_name => 'OUT_BAT',
argument_position => 1,
argument_name => 'DAILY',
argument_type => 'varchar2',
default_value => 'DAILY');
sys.dbms_scheduler.enable(name => 'OUT_BAT');
then of course the rest elements of dbms_scheduler job.

Ada: Adding an exception in a separate procedure when reading a file

This is a follow-up of this question: Ada: reading from a file .
I would like to add an exception that checks if the file that I'm opening actually exists or not. I have made a separate procedure to avoid code clutter.
Here is the main code test_read.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Long_Float_Text_IO;
with Ada.Float_Text_IO;
procedure Test_Read is
Input_File : File_Type;
Value : Long_Float;
procedure Open_Data (File : in Ada.Text_IO.File_Type; Name : in String) is separate;
begin
Ada.Text_IO.Open (File => Input_File, Mode => Ada.Text_IO.In_File, Name => "fx.txt");
while not End_Of_File (Input_File) loop
Ada.Long_Float_Text_IO.Get (File => Input_File, Item => Value);
Ada.Long_Float_Text_IO.Put (Item => value, Fore => 3, Aft => 5, Exp => 0);
Ada.Text_IO.New_Line;
end loop;
Ada.Text_IO.Close (File => Input_File);
end Test_Read;
And here is the separate body test_read-open_data.adb of the procedure Open_Data:
separate(test_read)
procedure Open_Data (File : in out Ada.Text_IO.File_Type;
Name : in String) is
--this procedure prepares a file for reading
begin
begin
Ada.Text_IO.Open
(File => File,
Mode => Ada.Text_IO.In_File,
Name => Name);
exception
when Ada.Text_IO.Name_Error =>
Ada.Text_IO.Put(File => Standard_Error, Item => "File not found.");
end;
end Open_Data;
On compilation I get an error message in the separate body test_read-open_data.adb:
actual for "File" must be a variable
How to fix this?
Thanks a lot...
Update:
I have now made the following corrections.
In test_read.adb, I now have procedure Open_Data (File : in out Ada.Text_IO.File_Type; Name : in String) is separate;
Updated the definition of the same Open_Data procedure in test_read-open_data.adb.
The program compiles well though I do not see it catch the exception say if I renamed the file fx.txt to fy.txt. The error message I get is just
raised ADA.IO_EXCEPTIONS.NAME_ERROR : fx.txt: No such file or directory
So I do not get my own error message :File not found.
What is still wrong?
The File parameter of Open_Data needs to be an in out parameter (as in, for example, Ada.Text_IO.Create), because you want the opened file to be accessible within Test_Read.
You are getting actual for "File" must be a variable because an in parameter is read-only.
procedure Open_Data (File : in out Ada.Text_IO.File_Type;
Name : in String) is
(Personally I rarely type the in mode, because it’s the default).
But in any case, it looks as though the reason for the observed behaviour is that Test_Read doesn’t actually call Open_Data!
(edited to make the recommended mode in out & to suggest calling Open_Data)
if your goal is to simply check if the file exists, consider using Ada.Directories.Exists
IIRC: Standard_Error is not a file, but a Stream.
I suspect that the reason you are not seeing your error message is that you are using Put rather than Put_Line. Different implementations/platforms treat output to the user's display differently. To be extra sure you will see the message, follow the Put_Line with a Get_Line. The Get_Line generally forces the output of the Put_Line.

Resources