Recent

Author Topic: How do I set the file position for BlockWrite?  (Read 479 times)

Firewrath

  • New member
  • *
  • Posts: 25
How do I set the file position for BlockWrite?
« on: May 22, 2019, 09:18:51 pm »
So while I was messing with opening files and Arrays, I partly made a semi-delta copying program.
...which I don't have the code with me because I wasn't planning on posting yet. -_-
But I started with the tutorial piece below.

So I have it comparing files with md5 hashes of the file sections*, but after I done all that I was at a loss as to how BlockWrite works for file position.
(*I just convert the 'Block' array into a string and hash that.)
I Think if I get a hash match, I can skip the call to BlockWrite, BUT if I do that, then from what I've read, the next BlockWrite will just start writing to the file at the same position as the skipped one. (Right?)
So How do I 'move' the BlockWrite 'start' position?

Tutorial Code:
Code: Pascal  [Select]
  1. program FilesCopy2;
  2. {$mode objfpc}{$H+}
  3. uses
  4. {$IFDEF UNIX}{$IFDEF UseCThreads}
  5. cthreads,
  6. {$ENDIF}{$ENDIF}
  7. Classes, SysUtils
  8. { you can add units after this };
  9. var
  10. SourceName, DestName: string;
  11. SourceF, DestF: file;
  12. Block: array [0 .. 1023] of Byte;
  13. NumRead: Integer;
  14. begin
  15.   Writeln('Files copy');
  16.   Write('Input source file name: ');
  17.   Readln(SourceName);
  18.   Write('Input destination file name: ');
  19.   Readln(DestName);
  20.  
  21.   if FileExists(SourceName) then
  22.   begin
  23.     AssignFile(SourceF, SourceName);
  24.     AssignFile(DestF, DestName);
  25.     FileMode:= 0;
  26.     // open for read only
  27.     Reset(SourceF, 1); // open source file
  28.     Rewrite(DestF, 1); // Create destination file
  29.     // Start copy
  30.     Writeln('Copying..');
  31.    
  32.     while not Eof(SourceF) do
  33.     begin
  34.       // Read Byte from source file
  35.       BlockRead(SourceF, Block, SizeOf(Block), NumRead);
  36.       // Write this byte into new destination file
  37.       BlockWrite(DestF, Block, NumRead);
  38.     end;
  39.     CloseFile(SourceF);
  40.     CloseFile(DestF);
  41.   end
  42.   else // Source File not foundWriteln('Source File does not exist');
  43.     Write('Copy file is finished, press enter key to close..');
  44.     Readln;
  45. end.
  46.  
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

winni

  • New member
  • *
  • Posts: 14
Re: How do I set the file position for BlockWrite?
« Reply #1 on: May 22, 2019, 09:40:01 pm »
Solution 1:

Code: Pascal  [Select]
  1. Type  TBlock = array[0..1023] of byte;
  2.  
  3. var SourceF, DestF : File of TBlock;
  4.  
  5. ....
  6. ....
  7. // seek for block 77
  8. seek (SourceF,77)
  9. blockread ....
  10. ...
  11.  
Now you can read block 77 with blockread - or write block 77 with blockwrite



Solution 2:

Code: Pascal  [Select]
  1. var SourceF, DestF : File of byte;
  2.  
  3. ......
  4. ......
  5. // seek for block 77:
  6. seek (SourceF, 77 * 1024);
  7.  
  8.  

Now  as above. But this hase the advantage, that you can postion to single bytes
and read them:


Code: Pascal  [Select]
  1. vat B : byte;
  2. // read byte 23
  3. seek (SourceF,23);
  4. read (SourceF,B);
  5.  


Good old file I/O. Dont't forget it!

Winni

Firewrath

  • New member
  • *
  • Posts: 25
Re: How do I set the file position for BlockWrite?
« Reply #2 on: May 22, 2019, 10:51:44 pm »
Awesome. Thank you. I was googling that a couple hours, at least. -_-

Good old file I/O. Dont't forget it!

I'm sure I will. :P
But that's marking favorites and my 'text file of pascal code' is for.  :D
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

furious programming

  • Sr. Member
  • ****
  • Posts: 327
  • I click a little.
Re: How do I set the file position for BlockWrite?
« Reply #3 on: May 23, 2019, 04:27:08 pm »
@Firewrath: just use the TFileStream class and keep the code short and simple.
Lazarus 2.0.2 with FPC 3.0.4, Windows XP (all 32-bit)

Thaddy

  • Hero Member
  • *****
  • Posts: 7991
Re: How do I set the file position for BlockWrite?
« Reply #4 on: May 23, 2019, 06:27:48 pm »
@Firewrath: just use the TFileStream class and keep the code short and simple.
That what I would advise too, but here: You need a file of <record> not a file of byte to get the similar equivalent.
This is all in the manuals. But a simple lesson is here: http://www.pascal-programming.info/lesson11.php "Binary files and records"
« Last Edit: May 23, 2019, 07:27:50 pm by Thaddy »
Hamlet 1.4 (nothing wrong with the Danish, btw)

Firewrath

  • New member
  • *
  • Posts: 25
Re: How do I set the file position for BlockWrite?
« Reply #5 on: May 30, 2019, 12:59:00 am »
@Firewrath: just use the TFileStream class and keep the code short and simple.

Actually, I find TFileStream more confusing then BlockRead/Write for some reason. I've read post on the forum here that TFileStream is slower?
So I'm not sure.
I plan on learning it some day though, but for now I want to see if I can make this with what I understand, even if partly. :P


That what I would advise too, but here: You need a file of <record> not a file of byte to get the similar equivalent.

Arn't records of a fixed size?
I havn't really messed with them, but from what I read I thought they were fixed, and how would I open a file and get a byte array with a record?
or am I over thinking it and I should use the FileStream Buffer for that?

I'll be honest I'm still confused as to how all that will work.
Once I get the current Block-Hash copying program finished, I'll post it on here and you all can tell me how bad I messed up then. :P
Sorry. I currently don't have Internet Access. So my replies might take a week. -_-

jamie

  • Hero Member
  • *****
  • Posts: 1547
Re: How do I set the file position for BlockWrite?
« Reply #6 on: May 30, 2019, 01:58:38 am »
pascal file control is pretty basic...

AFileID :File of Byte;

That makes the record size 1 byte so when reading and writing each iteration is one byte.

doing blockreads or writes can also follow this however, if you don't specify the type after the file...
then with the Reset(FileID, SizeOfRecord); is required.

FileID:File; is an untyped file and the default size is 128 bytes if you don't specify the size in the RESET procedure.
 
 You do have an optional parameter to report the actual records read in case you ask for more than there is.

 Using Seek(FileId, LocationFromStart);
 
 This moves the file pointer via record size..
 so if the file is of a BYTE or Record size was 1 it moves the actual pointer 1 byte.
if you have a File of WORD for example and you indicate 1 in the seek, it moves it 1 record but
in the real world it actually moved it 2 bytes because that is the size of the record (WORD)

« Last Edit: May 30, 2019, 02:02:30 am by jamie »

furious programming

  • Sr. Member
  • ****
  • Posts: 327
  • I click a little.
Re: How do I set the file position for BlockWrite?
« Reply #7 on: May 30, 2019, 04:02:56 am »
Actually, I find TFileStream more confusing then BlockRead/Write for some reason.

So don't be confused anymore and use the modern and convenient things, just like TFileStream class. Currently you are wasting the time instead of writing a code.

Quote
I've read post on the forum here that TFileStream is slower?

Even if (or rather for sure), how much slower? Microseconds? Hmm?
Lazarus 2.0.2 with FPC 3.0.4, Windows XP (all 32-bit)