adding data to a previously created file ( in the middle )

Hi folks,

I have this problem, i need to insert new data into a file  between 2 chunks of previously created data, now my question is how do i "split" the data to fit the new one?

let's say i have data records 1,2 and 3 and i need to add new data between 1,2 and 3.

i would probably come to some sort of an answer myself, but since i need this done yesterday :) i thought i'd ask the more experienced.

I'd appriciate any tips you may have
thanks in advance

BigozsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

BatalfCommented:
OK, let's think about this array :

TYPE
MYRECORD = RECORD
 name : string;
 age : integer;
end;


myarraytype = array[1..100] of myrecord;

VAR
  myarray : myarraytype;
  name : string;
  age : integer;
  position : integer;
  i : integer;

BEGIN
   {i guess you have som code for inserting, retreving data to the array}
   readln(name);
   readln(age);
   
   writeln('At what pos. do you want to have this record in the array?');
   readln(position);
 
   for i:=100 downto position+1 do
   myarray[i]:=myarray[i-1];
{makes room for the new record}
   myarray[position].name:=name;
   myarray[position].age := age;
{puts in the new record}

END.


 
   
   

 
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BigozsAuthor Commented:
this is good, when the data is not already written to a file, i was thinking of a possibility of doing this, after some data has been written to a file, and saved...

let's say i saved 1,2 and 3... and a day after i wanted to insert between 1,2 and 3 ... something...

that's the situation i was mentioning :)

sorry if i was unclear =)
0
BatalfCommented:
Could this help you?

Read the file first, and then after
the correction, save it again.

TYPE
MYRECORD = RECORD
 name : string;
 age : integer;
end;


myarraytype = array[1..100] of myrecord;

VAR
  myarray : myarraytype;
  name : string;
  age : integer;
  position : integer;
  i : integer;
  recordfile : file of myarraytype;

BEGIN
   assign(recordfile,'c:\filename.txt');
   reset(recordfile);
   read(recordfile, myarray);
   close(recordfile);
   {i guess you have som code for inserting, retreving data to the array}
   readln(name);
   readln(age);
   
   writeln('At what pos. do you want to have this record in the array?');
   readln(position);
 
   for i:=100 downto position+1 do
   myarray[i]:=myarray[i-1];
{makes room for the new record}
   myarray[position].name:=name;
   myarray[position].age := age;
{puts in the new record}

   assign(recordfile,'c:\filename.txt');
   rewrite(recordfile);
   write(recordfile, myarray);
   close(recordfile);
   

END.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

_lychee_Commented:
if u can divide ur file into 'chunks' (as opposed to sequential data), u can store the location (in the file) of the next piece of data after each piece of data... then insertion in the middle simply means writing to the file, adjusting the location of next piece for this piece, and the location of the previous piece's next piece location... something like linked lists
0
BigozsAuthor Commented:
how do i do what lychee_ mentioned?
0
BatalfCommented:
Hi

Just a little question :

The new data u want to put in, is it of the same type as the previosly saved.

Ex :

MYRECORD = RECORD
 name : string;
 age : integer;
end;

Let's think that an array of this record(datatype) are saved. Is the new record of the same type?(name and age)


0
BatalfCommented:
You could also assign the file to
be a file of myrecord(in stead of myarray). :

TYPE
MYRECORD = RECORD
 name : string;
 age : integer;
end;


myarraytype = array[1..100] of myrecord;

VAR
  myarray : myarraytype;
  recordfile : file of myrecord;

BEGIN
   assign(recordfile,'c:\filename.txt');
   reset(recordfile);

   for I:=1 to 100 do
   read(recordfile, myarray[i]);
 ......
 ......
 ......
 ......
   close(recordfile);    assign(recordfile,'c:\filename.txt');
   rewrite(recordfile);
   for I:=1 to 100 do
   write(recordfile, myarray[i]);
   close(recordfile);
   

END.
0
BatalfCommented:
Maybe I don't understand the question.

Let's say you have an array of records saved. Then you want to put in some data between 1 and 2, 2 and 3, 3 and 4.

right?

Then I think the solution could be to :
1. Read from the file
2. Make corrections to the array
3. Write the new array to the file

1. Read from file(already explained above)
2. Make corrections :

for i:=100 downto position+1 do
   myarray[i]:=myarray[i-1];
{makes room for the new record}
   myarray[position].name:=name;
   myarray[position].age := age;
{puts in the new record}

this puts in the new record between 1 and 2 if the "position" variable are set to 2.

Batalf
0
BigozsAuthor Commented:
hmmm, english not being my native langauge seems to create problems, Ok, here's it more explained.

i have a data file i need to creat, with let's say age and name. so i add a couple of "data cells" to the file... let's say i added

21 and Lisa
22 and Mike
23 and whatever

then i saved the file, after a day i came back and i needed to have a NEW data entery into a file between the first and second "data cell" that already exist in the file, like so:



21 Lisa

<------- new data here ex. 29 whatever2

22 Mike
23 whatever
 
then i'd like to save, and the next time i open the file i'd like to read

21 Lisa
29 whatever2
22 Mike
23 whatever

.... sigh :) i hope it's more clear now

0
HypoCommented:
I've think I understand what you want now... What you need is a procedure to insert data in a file!

Check out my sample, the first time you run it, the file TEST.TST will be created with 4 entry's in it (0..3)
The second time you run it, TEST.TST will be altered! entry 7 will be inserted between entry 2 and 3. I THINK that the procedure InsertInFile is what you need.

This is how you could use InsertInFile:

Parameter1 "_File" is the name of the file you want to alter.

Parameter2 "DataBlock" is the data you want to insert in the file

Parameter3 "Pos" is where in the file you want to insert "DataBlock"

Parameter4 "Size" is the size of the "DataBlock" you want to insert.

See the ExampleCode!


{$I-}
Program InsertTest;
uses crt,dos;

Type MyRecord = record
     Number : string[2];
     Name   : string[20];
     Dummy  : integer;
end;


var F     : file;
    DataR : array[0..3] of MyRecord;
    lp    : word;

Procedure InsertInFile(_File : string; var DataBlock; Pos : longint; Size : word);
Type  FileBuffer = array[0..31999] of byte;

var  F        : File;
     FSize,
     DataTBM,
     DataTBW  : longint;
     FBuff    : ^FileBuffer;
begin
 Assign(F,_File);
 If IOResult <> 0 then Exit;
 Reset(F,1);
 If IOResult <> 0 then Exit;
 FSize := FileSize(F);
 If Pos <= FSize then begin
  Getmem(FBuff,32000);
  DataTBM := Fsize-Pos;
  if (DataTBM >= 0) then begin
   Seek(F,FSize);
   BlockWrite(F,FBuff^,Size);
   repeat
    If DataTBM > 32000 then begin
     Seek(F,Pos+DataTBM-32000);
     BlockRead(F,FBuff^,32000);
     DataTBW := 32000;
     Dec(DataTBM,32000);
    end else begin
     Seek(F,Pos);
     BlockRead(F,FBuff^,DataTBM);
     DataTBW := DataTBM;
     DataTBM := 0;
    end;
    Seek(F,Fsize+Size-DataTBW);
    BlockWrite(F,FBuff^,DataTBW);
   until DataTBM = 0;
   Seek(F,Pos);
   BlockWrite(F,DataBlock,Size);
  end;
  Freemem(FBuff,32000);
 end;
 Close(F);
end;

begin
 DataR[0].Name := 'Hugo';
 DataR[1].Name := 'Henric';
 DataR[2].Name := 'Anna';
 DataR[3].Name := 'Alex';
 for lp := 0 to 3 do begin
  str(lp,DataR[lp].Number);
  DataR[lp].Dummy := $0A0D;
 end;
 assign(F,'Test.tst');
 reset(F,1);
 if IOResult = 0 then begin
  str(7,DataR[0].Number);
  DataR[0].Name := 'Arne';
  InsertInFile('Test.TST',DataR,3*SizeOf(MyRecord),SizeOf(MyRecord));
  Writeln('File TEST.TST has been altered!');
 end else begin
  rewrite(F,1);
  BlockWrite(F,DataR,Sizeof(DataR));
  close(F);
  Writeln('File TEST.TST has been Created!');
 end;
end.
0
BatalfCommented:
You can do what you ask for if you follow my proposed answer.

1. read the file
  assign(recordfile,'c:\filename.txt');
   reset(recordfile);
   read(recordfile, myarray);
   close(recordfile);
   
2. correct the array(put in the new record)
for i:=100 downto position+1 do
   myarray[i]:=myarray[i-1];
{makes room for the new record.
For your example position:=2}
   myarray[position].name:='Whatever';
   myarray[position].age := 29;

'100' is just something I put in(let's say you want to save an array of 100 records)

3. save the array again.  
  assign(recordfile,'c:\filename.txt');
  rewrite(recordfile);
  write(recordfile, myarray);
  close(recordfile);

The new record has now been saved to the file.

Regards
Batalf
0
BatalfCommented:
PS. When I was programming Pascal, I used this procedure on things like Hall of fame and so on.
0
BigozsAuthor Commented:
i'm afraid i'm completely lost now :( i have a piece of code saving 2 names and two numbers correctly, but i can't seem to incorporate any of your suggestions.

:(
0
HypoCommented:
should this file be a text file or a file file containing bytes, words strings etc...
0
HypoCommented:
Oh forgot... have you tryed my example?
0
BigozsAuthor Commented:
Hypo- yes, but it looks like i'm not allowed to use undesigned filetypes (Block read/write etc ) , been told to use pointers... wish i had more time, 3 days is way too little for my little knowlege in i/o ( generally in pascal )
0
BigozsAuthor Commented:
Hypo- yes, but it looks like i'm not allowed to use undesigned filetypes (Block read/write etc ) , been told to use pointers... wish i had more time, 3 days is way too little for my little knowlege in i/o ( generally in pascal )
0
BatalfCommented:
Maybe I'm the one that's completely lost here :-)

My point or suggestion is to
first read the array from the file.
Then put in the new record and then save the file again.

Then, the next time you open the file, the array will contain the new record.

Maybe it will become clearer if you type in your source code, or at least the structure of the data you save to your file.

Batalf
0
BatalfCommented:
What is the problem about my suggestion?
0
BatalfCommented:
Could you try to execute the code below and look at it?

PROGRAM FILECORRECTION;
USES
  Crt;
CONST
   N = 100;{the number of records the array could have}
TYPE
   myrecord = RECORD
       name : string[30];
      age : integer;
   end;
   myarraytype = array[1..N] of myrecord;

VAR
      myarray : myarraytype;
      myfile : file of myarraytype;
      i : integer;

begin
      {make all records empty}
      for i:=1 to 100 do
      begin
            myarray[i].name:='';
            myarray[i].age:=0;
      end;
      
      {the code below gives you what you have in
      the file at first. Just for example : }
      myarray[1].name:='Lisa';
      myarray[1].age:=21;
      myarray[2].name:='Mike';
      myarray[2].age:=22;
      myarray[3].name:='Whatever';
      myarray[4].age:=23;

       assign(myfile, 'c:\myfile.txt');
      rewrite(myfile);
      write(myfile,myarray);
      close(myfile);

      {Now, we are standing were you are when
      you open your files to put in a new record
--------------------------------------------}


{In my code, you don't need the 'read from file below,
but I put it in as an example because this is were you
stand I suppose}

      assign(myfile, 'c:\myfile.txt');
      reset(myfile);
      read(myfile, myarray);
      close(myfile);

      {now you want to put in 29 Whatever2
      between record 1 and 2 in the array}

      for i:=N downto 3 do
            myarray[i]:=myarray[i-1];

      {now you could put in your new record
      in myarray[2] because the records number
      2-3 (mike and whatever) has been moved
      to record 3 and 4}

      myarray[2].name:='Whatever2';
      myarray[2].age:=29;

      {now, it's time to write the new array
      to the file}

      assign(myfile, 'c:\myfile.txt');
      rewrite(myfile);
      write(myfile,myarray);
      close(myfile);

      writeln('This is your new array :');
        for i:=1 to 4 do
            writeln(myarray[i].name, myarray[i].age);

        readln;

end.
0
_lychee_Commented:
what i meant in my first post was that u store a pointer to the next record in the file...

for eg. taking ur age and name data...

originally, the file would look like so (this is only an eg; the format need not be like that):

1
1: 21 Lisa, 2
2: 22 Mike, 3
3: 23 whatever, -1

the 1:, 2:, 3: are the locations in the file (they're not stored)
the 1 at the start is the location of the first record
the number after the comma is the location of the next record
the -1 denotes the end of file

so if u wanna add '29 whatever' just after Lisa, just change Lisa's number and add 29 to the end like so:

1
1: 21 Lisa, 4       <- changed
2: 22 Mike, 3
3: 23 whatever, -1
4: 29 whatever2, 2  <- changed
0
_lychee_Commented:
urm... just a note...

1) if u wanna do this, i suggest u have a 'size' field at the start to indicate how big the file is...

2) when reading, maintain a fileposition array that contains where that element is.. this will allow u to avoid reading many times from the file to find out where to write the change...

pls comment if u need more info..
0
_lychee_Commented:
urm... just a note...

1) if u wanna do this, i suggest u have a 'size' field at the start to indicate how big the file is...

2) when reading, maintain a fileposition array that contains where that element is.. this will allow u to avoid reading many times from the file to find out where to write the change...

pls comment if u need more info..
0
HypoCommented:
How come you're not allowed to use undefined filetypes...  And what type and where are you supposed to use pointers?
0
BatalfCommented:
??
0
bakry99Commented:
Hi
Pls try this
{Pefore Using this procedure you most creat a file named "MainFile.dat"}
Type
 TRec= Record
    Id: Integer;
    Name:String[30];
    Age:Byte;
  end;
Var
 f: File of TRec;{Main file}
Procedure InsertRec(x: TRec; Pred: Integer);
{Pred: Mean The Id of pred Record }
{x : The Record Ypu want to inser}
var
Temp: File of TRec;
y: TRec;
Begin
  Assign(f, 'MainFile.Dat');
  Reset(f);
  Assign(Temp, 'TempFile.Dat');
  ReWrite(Temp);
  While Not Eof(f) do
    begin
      Read(f, y);
      Write(Temp, y);
      if y.id=Pred then
         Write(Temp, x);
    end;
  Close(f);
  Close(Temp);
  Erase(f);
  Rename(temp, 'MainFile.Dat');
end;
0
BatalfCommented:
??
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Pascal

From novice to tech pro — start learning today.