Recent

Author Topic: Find out the size of the set of files  (Read 1167 times)

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Find out the size of the set of files
« on: June 01, 2019, 02:52:19 pm »
Hello dear friends!

I have a large file list in the database (full path with file name and extension). I need everyone to specify the size.

Now I use the following:

Code: Pascal  [Select]
  1. MyListMedia: TStringList;
  2.      N:word;
  3.      MassivMediaStr: array of array of string;
  4. V1: LongInt;
  5.  MyFile: File;
  6. begin
  7.  
  8. SetLength(MassivMediaStr, MyListMedia.Count, 2);
  9.     for N := 0 to MyListMedia.Count - 1 do
  10.   begin
  11.     if MyListMedia.Count > N then
  12.     begin
  13.     AssignFile(MyFile, MyListMedia[N]);
  14.     Reset(MyFile, 1 );
  15.     V1:= FileSize(MyFile);  
  16.     MassivMediaStr[N][0] := UTF8ToSys(MyListMedia[N]);
  17.     MassivMediaStr[N][1] := IntToStr(V1 Div 1024) + ' KB';
  18.     end;
  19.   end;
  20.  

This algorithm works, but with a large number of array elements it gives out "access denied".
« Last Edit: June 01, 2019, 02:54:14 pm by mrkaban »

howardpc

  • Hero Member
  • *****
  • Posts: 3199
Re: Find out the size of the set of files
« Reply #1 on: June 01, 2019, 03:02:46 pm »
Perhaps because the OS runs out of file handles.

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Re: Find out the size of the set of files
« Reply #2 on: June 01, 2019, 03:19:25 pm »
Perhaps because the OS runs out of file handles.
I tried to add "CloseFile (MyFile);" to the end of the cycle, but this did not solve the problem.

Please explain how this problem can be solved. I did not understand.

lucamar

  • Hero Member
  • *****
  • Posts: 2124
Re: Find out the size of the set of files
« Reply #3 on: June 01, 2019, 03:24:29 pm »
Try this slightly modified version:

Code: Pascal  [Select]
  1.   MyListMedia: TStringList;
  2.   N:word;
  3.   MassivMediaStr: array of array of string;
  4.   V1: LongInt;
  5.   MyFile: File;
  6. begin
  7.   SetLength(MassivMediaStr, MyListMedia.Count, 2);
  8.   for N := 0 to MyListMedia.Count - 1 do
  9.   begin
  10.     if MyListMedia.Count > N then
  11.     begin
  12.       AssignFile(MyFile, MyListMedia[N]);
  13.       Reset(MyFile, 1 );
  14.       try
  15.         V1:= FileSize(MyFile);  
  16.         MassivMediaStr[N][0] := UTF8ToSys(MyListMedia[N]);
  17.         MassivMediaStr[N][1] := IntToStr(V1 Div 1024) + ' KB';
  18.       finally
  19.         CloseFile(MyFile)
  20.       end;
  21.     end;
  22.   end;
  23. end;
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

Bram71

  • New Member
  • *
  • Posts: 23
Re: Find out the size of the set of files
« Reply #4 on: June 01, 2019, 03:29:22 pm »
I would use findfirst, findnext and findclose and use the TSearchRec.filesize

See https://www.freepascal.org/docs-html/rtl/sysutils/findfirst.html

There is an example on the bottom of the page...

Also see https://www.freepascal.org/docs-html/rtl/sysutils/trawbytesearchrec.html

If you search for the exact filename + extension if applicable, then just use findfirst and findclose...
« Last Edit: June 01, 2019, 03:34:53 pm by Bram71 »

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Re: Find out the size of the set of files
« Reply #5 on: June 01, 2019, 03:32:31 pm »
Try this slightly modified version:

Code: Pascal  [Select]
  1.   MyListMedia: TStringList;
  2.   N:word;
  3.   MassivMediaStr: array of array of string;
  4.   V1: LongInt;
  5.   MyFile: File;
  6. begin
  7.   SetLength(MassivMediaStr, MyListMedia.Count, 2);
  8.   for N := 0 to MyListMedia.Count - 1 do
  9.   begin
  10.     if MyListMedia.Count > N then
  11.     begin
  12.       AssignFile(MyFile, MyListMedia[N]);
  13.       Reset(MyFile, 1 );
  14.       try
  15.         V1:= FileSize(MyFile);  
  16.         MassivMediaStr[N][0] := UTF8ToSys(MyListMedia[N]);
  17.         MassivMediaStr[N][1] := IntToStr(V1 Div 1024) + ' KB';
  18.       finally
  19.         CloseFile(MyFile)
  20.       end;
  21.     end;
  22.   end;
  23. end;
"TryFinallyEnd" did not help = (Anyway, the error.

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Re: Find out the size of the set of files
« Reply #6 on: June 01, 2019, 03:34:10 pm »
I would use findfirst, findnext and findclose and use the TSearchRec.filesize

See https://www.freepascal.org/docs-html/rtl/sysutils/findfirst.html

There is an example on the bottom of the page...

Code: Pascal  [Select]
  1. MyListMedia := FindAllFiles(put, '*.mp3;*.avi;*.mp4;*.mpg', true);

I use "FindAllFiles", to genius is a simple function. With FindFirst, this will be a lot of lines of code.

The problem is clearly not in the search function, just remove the size definition, and everything is fine.

Bram71

  • New Member
  • *
  • Posts: 23
Re: Find out the size of the set of files
« Reply #7 on: June 01, 2019, 03:48:51 pm »
If you click on thru on the FindAllFiles function, you will see it uses the tsearchrec method internally.

If you want to have a quick solution then copy the TFileSearcher.Search routine and modify it to your needs, e.g. assign the tsearchrec.size to the value part of the stringlist name / value pair...

Bram71

  • New Member
  • *
  • Posts: 23
Re: Find out the size of the set of files
« Reply #8 on: June 01, 2019, 03:59:29 pm »
Just found a  even simpler solution... use the function

FileSize(const Filename: string): int64;

Its in the same fileutil as find all files

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Re: Find out the size of the set of files
« Reply #9 on: June 02, 2019, 07:25:48 am »
Just found a  even simpler solution... use the function

FileSize(const Filename: string): int64;

Its in the same fileutil as find all files

Code: Pascal  [Select]
  1. AssignFile(MyFile, MyListMedia[N]);
  2.     Reset(MyFile, 1 );
  3.     V1:= FileSize(MyFile);
  4.  

I apologize, but you just read the first post? I used the FileSize function from the very beginning.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: Find out the size of the set of files
« Reply #10 on: June 02, 2019, 08:04:48 am »
This algorithm works, but with a large number of array elements it gives out "access denied".

What OS are you on?
Are you sure your app has the right to open each one of these files?
Maybe some of these files are opened exclusively.
Try to adjust your code to log the files that fail.

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Re: Find out the size of the set of files
« Reply #11 on: June 02, 2019, 08:44:43 am »
This algorithm works, but with a large number of array elements it gives out "access denied".

What OS are you on?
Are you sure your app has the right to open each one of these files?
Maybe some of these files are opened exclusively.
Try to adjust your code to log the files that fail.

Operating system Windows 7, and how to make a registration so that it records somewhere only files that could not be opened or measured by their size?

You can just write all the files in a text file, but as soon as those that could not be opened?

sstvmaster

  • Full Member
  • ***
  • Posts: 131
Re: Find out the size of the set of files
« Reply #12 on: June 02, 2019, 10:34:44 am »
you can test this, it checks the IOResult for "Reset". (Line 13 ... 23)

Errorcodes can you find here: https://www.freepascal.org/docs-html/rtl/system/ioresult.html

Code: Pascal  [Select]
  1.   MyListMedia: TStringList;
  2.   N:word;
  3.   MassivMediaStr: array of array of string;
  4.   V1: LongInt;
  5.   MyFile: File;
  6. begin
  7.   SetLength(MassivMediaStr, MyListMedia.Count, 2);
  8.   for N := 0 to MyListMedia.Count - 1 do
  9.   begin
  10.     if MyListMedia.Count > N then
  11.     begin
  12.       AssignFile(MyFile, MyListMedia[N]);
  13.       {$i-} Reset(MyFile, 1 ); {$i+}
  14.       if IOResult <> 0 then
  15.       begin
  16.         // ... here you can write IOResult and file to log file
  17.       end else
  18.       begin
  19.         V1:= FileSize(MyFile);
  20.         MassivMediaStr[N][0] := UTF8ToSys(MyListMedia[N]);
  21.         MassivMediaStr[N][1] := IntToStr(V1 Div 1024) + ' KB';
  22.         CloseFile(MyFile)
  23.       end;
  24.     end;
  25.   end;
  26. end;
Lazarus 2.0.4 x32
Lazarus 2.1.0 Trunk x32
OS Win 7 32bit

mrkaban

  • Jr. Member
  • **
  • Posts: 58
    • КонтинентСвободы
Re: Find out the size of the set of files
« Reply #13 on: June 02, 2019, 11:14:07 am »
you can test this, it checks the IOResult for "Reset". (Line 13 ... 23)

Errorcodes can you find here: https://www.freepascal.org/docs-html/rtl/system/ioresult.html

Code: Pascal  [Select]
  1.   MyListMedia: TStringList;
  2.   N:word;
  3.   MassivMediaStr: array of array of string;
  4.   V1: LongInt;
  5.   MyFile: File;
  6. begin
  7.   SetLength(MassivMediaStr, MyListMedia.Count, 2);
  8.   for N := 0 to MyListMedia.Count - 1 do
  9.   begin
  10.     if MyListMedia.Count > N then
  11.     begin
  12.       AssignFile(MyFile, MyListMedia[N]);
  13.       {$i-} Reset(MyFile, 1 ); {$i+}
  14.       if IOResult <> 0 then
  15.       begin
  16.         // ... here you can write IOResult and file to log file
  17.       end else
  18.       begin
  19.         V1:= FileSize(MyFile);
  20.         MassivMediaStr[N][0] := UTF8ToSys(MyListMedia[N]);
  21.         MassivMediaStr[N][1] := IntToStr(V1 Div 1024) + ' KB';
  22.         CloseFile(MyFile)
  23.       end;
  24.     end;
  25.   end;
  26. end;

Thank! This helped to understand the cause of the error! The attribute "Read Only" is to blame! How can I protect the file size detection algorithm from the read-only flag?

totya

  • Hero Member
  • *****
  • Posts: 577
Re: Find out the size of the set of files
« Reply #14 on: June 02, 2019, 01:00:05 pm »
This helped to understand the cause of the error! The attribute "Read Only" is to blame! How can I protect the file size detection algorithm from the read-only flag?

Hi!

LOL. Is it a real question? This code works without any problem, even Program Files dir and readonly file:

Code: Pascal  [Select]
  1. uses
  2.    ,FileUtil;  
  3.  
  4. code:
  5.   ShowMessage(Format('FileSize: %d byte', [FileUtil.FileSize('c:\Program Files (x86)\_Test_\testfile.txt')]));
  6.