Recent

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

mrkaban

  • Jr. Member
  • **
  • Posts: 60
    • КонтинентСвободы
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: 4144
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: 60
    • КонтинентСвободы
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: 4219
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/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Bram71

  • New Member
  • *
  • Posts: 26
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: 60
    • КонтинентСвободы
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: 60
    • КонтинентСвободы
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: 26
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: 26
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: 60
    • КонтинентСвободы
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: 3112
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: 60
    • КонтинентСвободы
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

  • Sr. Member
  • ****
  • Posts: 299
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;
greetings Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

mrkaban

  • Jr. Member
  • **
  • Posts: 60
    • КонтинентСвободы
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: 720
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.  

 

TinyPortal © 2005-2018