How do i slice a file size into X peices ?

lets say i retrieve a file size, i want to chop/slice its size into 8 peices and store each peice in an array..

something like this...


type
  TArrayOfInt64 = Array [0..8] Of Int64;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, c: integer;
  iDiv : SmallInt;
  TotalFileSize: Int64;
  StartOffset_Array : TArrayOfInt64;
  EndOffset_Array   : TArrayOfInt64;
  iStart, iEnd : Int64;
  a: boolean;
begin
  a := true;
  TotalFileSize := get_file_size( fileURL );
  iDiv := 9;
  for c := 0 to 8 do
  begin
    if a = true then
    iStart := 0;
    begin
    iEnd   := TotalFileSize div iDiv;
    StartOffset_Array[c] := iStart;
    EndOffset_Array[c]   := iEnd;
    inc(iDiv);
    ShowMessageFmt( 'Start: %d, End: %d', [ StartOffset_Array[c], EndOffset_Array[c] ] );
    iStart := TotalFileSize div iDiv;
    a := false;
    end;
  end;

Open in new window

John6661Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
epasquierConnect With a Mentor Commented:
I haven't got much time to do it completely, but here is a starter. Look at Delphi help for the functions I'm using, to help you finish/fix whatever I left undone. I might also have complicated the thing by making the filesize of chunks a multiply of 2kb, and all the same size, except for the last file.

Const
 Block_Size=2048;
 File_Div=8;

Var
 F,F2: File of byte;
 block:Array [0..Block_Size-1] of Byte;
 fs:Int64;
 i,nf,bc,bc2:integer; // block count;
 br:integer;
begin
 AssignFile(F, 'SomeFile.bin'); 
 Reset(F) ;
 fs:=FileSize(F);
 bc:=(fs+Block_Size-1) Div Block_Size;
 bc2:=(bc+File_Div-1) Div File_Div;
for nf:=1 to File_Div do
 begin
  AssignFile(F2,'SomeFile'+IntToStr(nf)+'.bin');
  Rewrite(F2);
  for i:=0 to bc2-1 do
   begin
    BlockRead(F,block,Block_Size, rb);
    BlockWrite(F2,block,rb);
   end;
   CloseFile(F2);
 end;
 CloseFile(F);
end;

Open in new window

0
 
John6661Author Commented:
9 peices, sorry.
0
 
mlmccCommented:
What is the file?

DO you need to be able to put it back together?

mlmcc
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.

 
8080_DiverCommented:
Well, I'm not at all sure how this could make sense but it can be done.  Just determine how many bytes there are in the file, divide by 9 (as an integer) calling that AvgPiece, then multiply that number by 8 and subtract it from the original size calling taht FinalPiece.  Now, put the packets of AvgPiece size in the first 8 array cells and there rest of it (i.e. the piece that is FinalPiece size in the 9th cell.

You can reassemble it in the reverse of the above.
0
 
epasquierCommented:
about the 'storing file in an array' part of your question, I haven't quite understood it.
It either does not makes much sense (you don't put a file content in an array) or trivial : if you meant, having an array of records, each record saying the filename, file index 0..8, file size, file offset compared to origin file. etc... those informations can all be stored within the general loop I gave you that will physically split the files (on disk)

If you meant only split the files IN MEMORY, then the answer is trivial as well : calculate the size, use GetMem to reserve some memory and use BlockRead to read each part in ONE call.
The fact I used chunks of 2Kb in my sample is just because it is generally optimized that way to ensure that files are 2k or 4K aligned if possible.
But beware of the memory requirement if that is what you meant.

If I didn't answered your question in one or the other post, then you must tell us more about the context of your needs
0
 
John6661Author Commented:
I'm making a download accelerator for education purpose...

btw, i got it to work, although i will accept answers because you guys took effort for your answers..

here's my final solution (Note, this is a FireMonkey HD Application in XE2)

 
procedure TFireMonkeyDLClass.bStartDLClick(Sender: TObject);
type
  TArrayOfInt64 = Array [0..8] Of Int64;
var
  iForLoop: Integer;
  siEndDiv : SmallInt;
  i64TotalFileSize: Int64;
  StartOffset_Array : TArrayOfInt64;
  EndOffset_Array   : TArrayOfInt64;
  i64Start, i64End, i64End2 : Int64;
  bStartZero: boolean;
begin
  i64TotalFileSize := FileInfo.FileSize;

  bStartZero := True;

  siEndDiv := 9;

  for iForLoop := 0 to 8 do
  begin
    if ( bStartZero = true ) then
     i64Start := 0;

    i64End    := i64TotalFileSize div siEndDiv;
    i64End2   := i64End; // make a backup of for later use

    StartOffset_Array[iForLoop] := i64Start;
    EndOffset_Array[iForLoop]   := i64End;

    dec( siEndDiv );

  {  ShowMessageFmt( 'Start: %d, End: %d, %d',
   [ StartOffset_Array[iForLoop], EndOffset_Array[iForLoop], iForLoop ] ); }

    i64Start  := i64End2 + 1; // very important

    bStartZero := False;
  end;
end;

Open in new window

0
 
John6661Author Commented:
@mlmcc: let me explain it better..

i'm using CreateFile() to create a file, lets say .iso is the suffix...

there are 9 threads (9 connections to the server) that each thread uses InternetReadFile in a repeat/until loop with each thread has its own offset limit, each thread access the same file that was created using CreateFile and write to a different offset..
0
 
John6661Author Commented:
this is a multi-threaded application
0
 
John6661Author Commented:
thanks...
0
 
8080_DiverCommented:
Saving the best until the last (i.e. this is a multi-threaded application) makes it a bit more difficult to answer as does providing the extra information about it being a download application. ;-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.