How can I quickly reset the contents of a file?

I want to finish the file selected by the user from my program. I wrote this sample code:

var aFile: TFileStream; Const FileAddr: String = 'H:\Akon.mp3'; Buf: Byte = 0; begin if FileExists(FileAddr) then begin // Open given file in file stream & rewrite it aFile:= TFileStream.Create(FileAddr, fmOpenReadWrite); try aFile.Seek(0, soFromBeginning); while aFile.Position <> aFile.Size do aFile.Write(Buf, 1); finally aFile.Free; ShowMessage('Finish'); end; end; end; 

As you can see, I am rewriting this file with a 0 (zero) value. This code works correctly, but the speed is very high in large files. I would like to make this process in multi-threaded code, but I have tried some code testing and cannot do this. For example, I create 4 threads that do this work to speed up this process.

Is there a way to speed up this process?

+6
source share
5 answers

I don't know if this can help you, but I think you could do better (than multithreading) to write a larger buffer.
For example, you can initialize a 16k wide buffer and write directly to FileStream; you only need to check the last part of the file, for which you write only part of the full buffer.
Believe me, it will be really faster ...

+4
source

OK, I will bite:

 const FileAddr: String = 'H:\Akon.mp3'; var aFile: TFileStream; Buf: array[0..1023] of Byte; Remaining, NumBytes: Integer; begin if FileExists(FileAddr) then begin // Open given file in file stream & rewrite it aFile:= TFileStream.Create(FileAddr, fmOpenReadWrite); try FillChar(Buf, SizeOf(Buf), 0); Remaining := aFile.Size; while Remaining > 0 do begin NumBytes := SizeOf(Buf); if NumBytes < Remaining then NumBytes := Remaining; aFile.WriteBuffer(Buf, NumBytes); Dec(Remaining, NumBytes); end; finally aFile.Free; ShowMessage('Finish'); end; end; end; 
+4
source

Multiple threads will not help you. Your limitation is access to the disk, primarily because you write only 1 byte at a time.

Declare Buf as an array of bytes and initialize it using FillChar or ZeroMemory . Then modify the while loop as follows:

 while ((aFile.Position + SizeOf(Buf)) < aFile.Size) do begin aFile.Write(Buf, SizeOf(Buf)); end; if (aFile.Position < aFile.Size) then begin aFile.Write(Buf, aFile.Size - aFile.Position); end; 
+3
source

From the slowness of the code above, you should find out that:

  • Writing one byte at a time is the slowest and worst way to do this, you incur huge overhead and reduce overall performance.

  • Even writing 1 kbyte (1024 bytes) at a time will be a big improvement, but writing a large amount, of course, will be even faster until you reach the point of decrease in profit, which, I think, will be from 200 thousand to 500 thousand buffers records. The only way to find out when it becomes irrelevant for your application is to test, test, and test.

  • Checking the position against size is so often redundant. If you read the size once and write the correct number of bytes using a local variable, you will save more overhead and increase productivity. those. Inc (LPosition, BufSize) to increase LPosition: an integer boolean variable, the size of the BufSize buffer.

+2
source

Not sure if this meets your requirements, but it works fast too.

 var aFile: TFileStream; const FileAddr: String = 'H:\Akon.mp3'; begin if FileExists(FileAddr) then begin aFile:= TFileStream.Create(FileAddr, fmOpenReadWrite); try afile.Size := 0; finally aFile.Free; ShowMessage('Finish'); end; end; end; 

So there will be something in this direction (declaring b outside the function will improve your loop performance, especially when working with a large file). I assume that the application filename will have var :

 const b: byte=0; procedure MyProc; var aFile: TFileStream; Buf: array of byte; len: integer; FileAddr: String; begin FileAddr := 'C:\testURL.txt'; if FileExists(FileAddr) then begin aFile := TFileStream.Create(FileAddr, fmcreate); try len := afile.Size; setlength(buf, len); fillchar(buf[0], len, b); aFile.Position := 0; aFile.Write(buf, len); finally aFile.Free; ShowMessage('Finish'); end; end; end; 
0
source

Source: https://habr.com/ru/post/886487/


All Articles