function SplitFile(Filename, DestFolder:
string; SplitSize, CntParts: Int64): Integer;
function GetClusterSize(Drive: Char): Cardinal;
var
SectorPerCluster: Cardinal;
BytesPerSector : Cardinal;
NumberOfFreeClusters: Cardinal;
TotalNumberOfClusters: Cardinal;
begin
GetDiskFreeSpace(PChar(Drive + '
:\'), SectorPerCluster, BytesPerSector, NumberOfFreeClusters,
TotalNumberOfClusters);
Result := SectorPerCluster * BytesPerSector;
end;
var
hFile : THandle;
SizeOfFile : Int64;
hPart : THandle;
Loop : Cardinal;
Partname :
string;
BlockSize : Cardinal;
MemBuffer :
array of Byte;
minlen : Int64;
BytesToRead, BytesRead, BytesWritten: Integer;
OverallBytesRead : Int64;
ProgressCurrent, ProgressOld: Int64;
begin
TickStart := GetTickCount;
BlockSize := -(-GetClusterSize(FileName[1])
and -GetClusterSize(DestFolder[1])
and -1048576);
SetLength(MemBuffer, BlockSize - 1);
bRunning := 1;
OverallBytesRead := 0;
SizeOfFile := GetFileSize(PChar(Filename));
hFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL
or FILE_FLAG_SEQUENTIAL_SCAN
or FILE_FLAG_WRITE_THROUGH, 0);
if hFile <> INVALID_HANDLE_VALUE
then
begin
for Loop := 1
to CntParts
do
begin
// Reset variables
ProgressOld := 0;
BytesToRead := SplitSize;
// build filename of the parts
Partname := DestFolder + '
\' + ExtractFilename(Filename) + Format('
.%3.3d', [Loop]);
if FileExists(Partname)
then
DeleteFile(PChar(Partname));
hPart := CreateFile(PChar(Partname), GENERIC_WRITE, FILE_SHARE_WRITE,
nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL
or FILE_FLAG_SEQUENTIAL_SCAN
or FILE_FLAG_WRITE_THROUGH, 0);
if hPart <> INVALID_HANDLE_VALUE
then
begin
repeat
minlen := Min(length(MemBuffer), BytesToRead);
BytesRead := FileRead(hFile, MemBuffer[0], minLen);
if BytesRead > -1
then
begin
BytesWritten := FileWrite(hPart, MemBuffer[0], BytesRead);
Dec(BytesToRead, length(MemBuffer));
// progress stuff ////////////////////////////////////////////////////
OverallBytesRead := OverallBytesRead + BytesWritten;
ProgressCurrent := (OverallBytesRead * 100)
div SizeOfFile;
if ProgressCurrent <> ProgressOld
then
begin
ProgressOld := ProgressCurrent;
end;
SendMessage(hApp, FSM_PROGRESS, ProgressCurrent, Integer(PChar(Partname)));
end
else
begin
MessageBox(hApp, PChar(SysErrorMessage(GetLastError)), PChar(APPNAME), 0);
Break;
end;
//////////////////////////////////////////////////////////////////////
until (BytesToRead <= 0)
or (bRunning = 0);
end;
FileClose(hPart);
if bRunning = 0
then
Break;
end;
FileClose(hFile);
end;
SendMessage(hApp, FSM_FINISH, GetTickCount - TickStart, GetLastError());
result := GetLastError();
end;