• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 332
  • Last Modified:

How to create a segmented Textfile?

Can someone exlain a good and super fast method for writing Text into the middle of a Textfile?
0
Okey
Asked:
Okey
  • 4
  • 3
  • 2
  • +2
1 Solution
 
billiousCommented:
I severely doubt this can be done, if I read it aright.

I'd blockread the original up to the insertion point, writing out to a second "modified" file, then blockwrite the insertion, then blockread the remainder of the original and blockwrite it to modified.

delete the original and rename the modified and the job's done.

If you want to update in-place, then don't waste your time - you can't just insert bytes into the middle of a file.

...Bill
0
 
MannSoftCommented:
I think it could also be done without rewriting the file.  Something like:

-Seek to insertion point
-Blockread all the text up to the end of the file
-Seek to insertion point + sizeof(insertion text)
-Blockwrite the text you just blockread
-Seek to insertion point
-Blockwrite insertion text

This way you move the end of the file down X bytes making room for the new text.  On a large file where you cant make a single blockread you would have to work it a little differently.  You'd have to move the end of the file down block by block, starting with the very end and working up towards the insertion point.  That would ensure you dont overwrite any text that hasnt been moved yet.
0
 
VGRCommented:
agree with the above.
personally, for "super-fast" method I would (stupidely) use this :
-Assign / $I- / ReSet / $I+ / IOResult=0
-ReSet
-blockread first part,
-rewrite(newfile)
-blockwrite first part
-blockwrite inserted part
-blockread second part
-blockwrite second part
-close both
-delet first file
-rename newfile
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
grg99Commented:
If the new text is the exact same length as the old text, then it's easy.

Otherwise it's kinda slow.

A better question would be:  why do you want to do this, and would you consider alternatives.

0
 
billiousCommented:
Mannsoft:

Good idea, with a couple of drawbacks:

to use the method you suggest, you must be able to blockread a sufficient amount to memory. Suppose the insert-into position is @1K, length 1K in a 300M  file, for instance. Has the machine got 300M of available memory? If you write out the extra data to another file (even via paging) then you defeat the purpose.

The second problem is power or system failure, which Mr. Murphy dictates will happen any time after commencing to blockwrite. The file is then corrupted, since the block from insertionpoint + insertionsize will have been partially-written.

...Bill
0
 
MannSoftCommented:
In the last paragraph I already gave the alternative method for working with large files.  And having to insert a 1k chunk at the 1k mark of a 300m file, both ways will have pretty close to the same amount of reads/writes.  Inserting a 1k chunk at the 299.9m mark of a 300m file one way will outperform the other by leaps and bounds.

But you're right about power failure.  If you want speed I think my way is going to be the faster of the two (although Im not quite interested enough to actually benchmark them <g>).  If you want the extra safety then rewriting the file each time is definitely the way to go.  Worse case scenario there is power failure after the delete, but you'll still have the rewritten file you can manually rename after rebooting.
0
 
billiousCommented:
Mannsoft:

[academic]

I suppose I stopped reading as soon as I found what I regarded as a problem with the method. It would certainly be faster than re-writing the whole file (and use less space, since only originalsize + insertionsize would be required, against (2*originalsize) + insertionsize for the reconstruct method.

Nevertheless, I believe we are agreed that the extra safety offered by the rewrite method indicates that is the better path.

As ever, it's a question of swings and roundabouts.

...Bill
0
 
OkeyAuthor Commented:
OK I see I must explain the problem better!

I used to transfer a TEXT to a FILE VAR
(
 Copying Handle and RecSize into a FILE VAR
plus setting MODE to 55219
in something like this:

TFILEREC=RECORD
 HANDLE ,
 MODE,
 RECSIZE,
 BUFPOS{in TEXT ONLY},
 BUFEND{in TEXT ONLY}:WORD
 Garbage...
END;

Search the Help of Borlands TP7.0
for TTextRec and TFileRec
as FileRec or so ?????

)
then I use Seek, FILESIZE, FILEPOS, Blockread & Blockwrite with the new Filehandle and when I return to TEXT-VAR then I write only BufPOS:=BUFEND & READLN 2 times a Line
so TEXT-var would be positioned and so on!

Now my problem is that this is somehow buggy!
Fileposition of Lines in Text-VAR are somehow movin bytewise away when repeated seeked and READOUT with
ReadLn
How can I verryfied seek and search with this FastForward method into a textfile to especially copy segments from the center of several MB great TEXT-FILES
Segments have to be recognized, so if I seek too far I seek back until I am at least two readln's before the segment!
Segment is for analysis mentioned text that contains information that should be explained into it but only just segmentwise per loop!
I know Blockread is suiteable for Fast File IO
But It has to run with Textfiles too!
And  at Least I surely use IORESULT and so on!
0
 
VGRCommented:
so don't use a textfile but a file of byte ;-)
0
 
OkeyAuthor Commented:
I have to use TEXT-File,
because I Implemented several thousands of lines with!
Now I'm searching for a fast forward seek method to find the Segment in TEXT-File for copy, analyse and explain purposes. It's a source Text and has to be stuffed on with informations especially in the center!
I changed as far as possible to untyped FILE-var,
but I won't rebuild the complete TEXT-File-Handling
with EOF FLUSH WRITELN READLN (FILE- OPEN, WRITE/READ, FLUSH AND CLOSE)
Because it would lead to several hundreds of source lines!
I mean Borlands TP7,0 always does a Fileread when You use a Read/Ln no matter of the buffer
(
 Buffer will always be reloaded
)
That's why Text is too slow for a search through.
because the SetTEXTBuiffer sets only the maximum possible READ-Record for a File but doesn't do the read from buffer!

So if someone knows here a good/cheap trick
I'll listen to!
0
 
OkeyAuthor Commented:
Think about this:
You want to stuff a sorted File
with numered lines.
The Numbered lines have to be continously and in order written.
To add new lines in between the old I'll have to seek a verrified position I don't know,
so that I've to do a fast scan forward in TEXT-File.
but while it's growing up to several MB, I thought about a stepped seek forward and scanin on as far as the destination is behind the read position
elsewise I'm seeking back to last acceptable position before!
The Bug is that the Destination position is movin away while doing this.
I mean the Suggested line stops several bytes away from with Filepos found position.
I'am using the following :

TYPE{Definition of MZ-EXE header}
 TEXT_PTR=^TEXT;

  PTextBuf = ^TTextBuf;
  TTextBuf = array[0..127] of Char;

  PTRTFileRec=^TFileRec;
  TFileRec = record
    Handle  :                Word;
    Mode    :                Word;
    RecSize :                Word;
    Privat  :array[1..26] of Byte;
    UserData:array[1..16] of Byte;
    Name    :array[0..79] of Char;
  end;

  PTRTTextRec=^TTextRec;
  TTextRec = record
    Handle   :                Word;
    Mode     :                Word;
    BufSize  :                Word;
    Privat   :                Word;
    BufPos   :                Word;
    BufEnd   :                Word;
    BufPtr   :            PTextBuf;
    OpenFunc :             Pointer;
    InOutFunc:             Pointer;
    FlushFunc:             Pointer;
    CloseFunc:             Pointer;
    UserData :array[1..16] of Byte;
    Name     :array[0..79] of Char;
    Buffer   :            TTextBuf;
  end;

PROCEDURE SET_FILE_REC;
BEGIN
 WITH TYPED_FILE_RECORD Do
 Begin
  HANDLE:=TXTFILE^.HANDLE;
  MODE:=55219;{File mode for Reading/writing}
  RECSIZE:=1;
  FOR I:=0 TO 79 DO NAME[i]:=TXTFILE^.NAME[i];
 End;
END;

Procedure TEXTSEEK(TXTFILE:PTRTTextRec;POSITION:LONGINT);
VAR
 I:BYTE;
 TYPED_FILE_RECORD:TFILEREC;
 _FILE:^FILE;
Begin
 TXTFILE^.BUFEND:=0;
 With TXTFILE^ Do BufPos:=BufEnd;
 SET_FILE_REC;
 _FILE:=ADDR(TYPED_FILE_RECORD);
 REPEAT SEEK(_File^,POSITION); UNTIL IORESULT=0;
END;

Function TEXTPOS(TXTFILE:PTRTTextRec;RECORD_SIZE:WORD):LONGINT;
VAR
 I:BYTE;
 TYPED_FILE_RECORD:TFILEREC;
 _FILE:^FILE;
Begin
 SET_FILE_REC;
 _FILE:=ADDR(TYPED_FILE_RECORD);
 WITH TXTFILE^
  Do REPEAT
      TEXTPOS:=FILEPOS(_File^)-BUFEND+BUFPOS;
     UNTIL IORESULT=0;
END;

Function TEXTSize(TXTFILE:PTRTTextRec;RECORD_SIZE:WORD):LONGINT;
VAR
 I:BYTE;
 TYPED_FILE_RECORD:TFILEREC;
 _FILE:^FILE;
Begin
 SET_FILE_REC;
 _FILE:=ADDR(TYPED_FILE_RECORD);
 REPEAT TEXTSize:=FILESIZE(_File^);UNTIL IORESULT=0;
END;

Did I Implemented here a Bug ?
0
 
OkeyAuthor Commented:

oops I mean aehm this lines
(I'm sorry for old garbage I placed in the comment above!)

Procedure TEXTSEEK(TXTFILE:PTRTTextRec;POSITION:LONGINT);
VAR
 I:BYTE;
 TYPED_FILE_RECORD:TFILEREC;
 _FILE:^FILE;
Begin
 TXTFILE^.BUFEND:=0;
 With TXTFILE^ Do BufPos:=BufEnd;
 SET_FILE_REC;
 _FILE:=ADDR(TYPED_FILE_RECORD);
 REPEAT SEEK(_File^,POSITION); UNTIL IORESULT=0;
END;

Function TEXTPOS(TXTFILE:PTRTTextRec;RECORD_SIZE:WORD):LONGINT;
VAR
 I:BYTE;
 TYPED_FILE_RECORD:TFILEREC;
 _FILE:^FILE;
Begin
 WITH TYPED_FILE_RECORD Do
 Begin
  HANDLE:=TXTFILE^.HANDLE;
  MODE:=55219;{File mode for Reading and Reading/writing}
  RECSIZE:=RECORD_Size;
  FOR I:=0 TO 79 DO NAME[i]:=TXTFILE^.NAME[i];
 End;
 _FILE:=ADDR(TYPED_FILE_RECORD);
 WITH TXTFILE^
  Do REPEAT
      TEXTPOS:=FILEPOS(_File^)-BUFEND+BUFPOS;
     UNTIL IORESULT=0;
END;

Function TEXTSize(TXTFILE:PTRTTextRec;RECORD_SIZE:WORD):LONGINT;
VAR
 I:BYTE;
 TYPED_FILE_RECORD:TFILEREC;
 _FILE:^FILE;
Begin
 WITH TYPED_FILE_RECORD Do
 Begin
  HANDLE:=TXTFILE^.HANDLE;
  MODE:=55219;{File mode for Reading and Reading/writing}
  RECSIZE:=RECORD_Size;
  FOR I:=0 TO 79 DO NAME[i]:=TXTFILE^.NAME[i];
 End;
 _FILE:=ADDR(TYPED_FILE_RECORD);
 REPEAT TEXTSize:=FILESIZE(_File^);UNTIL IORESULT=0;
END;
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now