Subversion Repositories delphiutils

Rev

Rev 84 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
84 daniel-mar 1
unit FileReadCheckerMain;
2
 
3
interface
4
 
5
uses
6
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, FileCtrl, Math;
8
 
9
type
10
  TForm1 = class(TForm)
11
    Button1: TButton;
12
    Edit1: TEdit;
13
    Memo1: TMemo;
14
    Label1: TLabel;
15
    Label2: TLabel;
16
    ProgressBar1: TProgressBar;
17
    procedure Button1Click(Sender: TObject);
18
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
85 daniel-mar 19
    procedure FormCreate(Sender: TObject);
84 daniel-mar 20
  private
21
    procedure FindFiles(FilesList: TStrings; StartDir, FileMask: string; errorSL: TStrings=nil);
22
    procedure EnableDisableControls(enabled: boolean);
23
    function Readable(filename: string): boolean;
24
  end;
25
 
26
var
27
  Form1: TForm1;
28
 
29
implementation
30
 
31
{$R *.dfm}
32
 
33
// Recursive procedure to build a list of files
34
procedure TForm1.FindFiles(FilesList: TStrings; StartDir, FileMask: string; errorSL: TStrings=nil);
35
var
36
  SR: TSearchRec;
37
  DirList: TStrings;
38
  IsFound: Boolean;
39
  i: integer;
40
begin
41
  if StartDir[length(StartDir)] <> PathDelim then
42
    StartDir := StartDir + PathDelim;
43
 
44
  IsFound := FindFirst(StartDir+FileMask, faAnyFile-faDirectory, SR) = 0;
45
  while IsFound do
46
  begin
47
    Application.ProcessMessages;
48
    if Application.Terminated then Abort;
85 daniel-mar 49
 
50
    if FilesList.Count = FilesList.Capacity - 1 then
51
      FilesList.Capacity := FilesList.Capacity + 1000;
52
 
84 daniel-mar 53
    FilesList.Add(StartDir + SR.Name);
54
    IsFound := FindNext(SR) = 0;
55
  end;
56
  FindClose(SR);
57
 
58
  // Build a list of subdirectories
59
  DirList := TStringList.Create;
60
  IsFound := FindFirst(StartDir+'*.*', faAnyFile, SR) = 0;
61
  if DirectoryExists(StartDir) and not IsFound then
62
  begin
63
    // Every directory has always at least 2 items ('.' and '..')
64
    // If not, we have an ACL problem.
65
    if Assigned(errorSL) then errorSL.Add(StartDir);
66
  end;
67
  while IsFound do begin
68
    if ((SR.Attr and faDirectory) <> 0) and
69
         (SR.Name[1] <> '.') then
70
    begin
71
      Application.ProcessMessages;
72
      if Application.Terminated then Abort;
73
      DirList.Add(StartDir + SR.Name);
74
    end;
75
    IsFound := FindNext(SR) = 0;
76
  end;
77
  FindClose(SR);
78
 
79
  // Scan the list of subdirectories
80
  for i := 0 to DirList.Count - 1 do
81
  begin
82
    FindFiles(FilesList, DirList[i], FileMask, errorSL);
83
  end;
84
 
85
  DirList.Free;
86
end;
87
 
88
function TForm1.Readable(filename: string): boolean;
89
var
90
  ss: TFileStream;
91
begin
92
  result := false;
93
  if not FileExists(filename) then exit;
94
  try
95
    ss := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone);
96
    ss.Free;
97
    result := true;
98
  except
99
    exit;
100
  end;
101
end;
102
 
103
procedure TForm1.Button1Click(Sender: TObject);
104
var
105
  sl: TStringList;
106
  fil: string;
107
  cnt: integer;
108
  c1, c2, f: Int64;
109
  elapsedSecs: Int64;
110
begin
111
  if not DirectoryExists(edit1.Text) then
112
  begin
113
    raise Exception.CreateFmt('Directory %s does not exist!', [Edit1.Text]);
114
  end;
115
 
116
  QueryPerformanceFrequency(f);
117
  QueryPerformanceCounter(c1);
118
 
119
  EnableDisableControls(false);
120
  try
121
    Memo1.Lines.Clear;
122
    cnt := 0;
123
    sl := TStringList.Create;
124
    try
85 daniel-mar 125
      sl.Sorted := false;
84 daniel-mar 126
      sl.BeginUpdate;
127
      Label2.Caption := 'Scan folders ...';
128
 
129
      FindFiles(sl, edit1.text, '*', Memo1.Lines);
130
      Inc(cnt, Memo1.Lines.Count); // failed folders
131
 
132
      ProgressBar1.Max := sl.Count;
133
      ProgressBar1.Min := 0;
134
      ProgressBar1.Position := 0;
135
 
136
      for fil in sl do
137
      begin
138
        ProgressBar1.Position := ProgressBar1.Position + 1;
139
 
140
        if not Readable(fil) then
141
        begin
142
          Memo1.Lines.Add(fil);
143
          inc(cnt);
144
        end;
145
 
85 daniel-mar 146
        QueryPerformanceCounter(c2);
147
        elapsedSecs := Ceil((c2-c1)/f);
148
        Label2.Caption := MinimizeName(Format('[%.2d:%.2d:%.2d] %s', [elapsedSecs div 3600, elapsedSecs mod 3600 div 60, elapsedSecs mod 3600 mod 60, fil]), Label2.Canvas, Label2.Width);
84 daniel-mar 149
 
150
        Application.ProcessMessages;
151
        if Application.Terminated then Abort;
152
      end;
153
      sl.EndUpdate;
154
    finally
155
      sl.Free;
156
    end;
157
 
158
    if not Application.Terminated then
159
    begin
160
      QueryPerformanceCounter(c2);
161
      elapsedSecs := Ceil((c2-c1)/f);
162
 
85 daniel-mar 163
      ShowMessageFmt('Finished. Found %d error(s). Elapsed time: %.2d:%.2d:%.2d', [cnt, elapsedSecs div 3600, elapsedSecs mod 3600 div 60, elapsedSecs mod 3600 mod 60]);
84 daniel-mar 164
    end;
165
  finally
166
    EnableDisableControls(true);
167
  end;
168
end;
169
 
170
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
171
begin
172
  Application.Terminate;
173
end;
174
 
85 daniel-mar 175
procedure TForm1.FormCreate(Sender: TObject);
176
begin
177
  DoubleBuffered := true;
178
 
179
  {$IFDEF UNICODE}
180
  Caption := Caption + ' [Unicode]';
181
  {$ELSE}
182
  Caption := Caption + ' [ANSI]';
183
  {$ENDIF}
184
end;
185
 
84 daniel-mar 186
procedure TForm1.EnableDisableControls(enabled: boolean);
187
begin
188
  Button1.Enabled := enabled;
189
  Label1.Enabled := enabled;
190
  Edit1.Enabled := enabled;
85 daniel-mar 191
  // Memo1.Enabled := enabled; // is already readonly by default
84 daniel-mar 192
end;
193
 
194
end.