FindFirstでリソース不足に陥る

解決


かず  2010-09-25 17:02:25  No: 39215

Delphi2010pro、WinXP環境
FindFirstを使用し該当するファイル情報を取得する処理ですが
処理量が多いと「システムリソースが足りません」と表示されます。
FindFirstに関していろいろ情報がありますが、この動作は未解決のままなのでしょうか
var
  sr : TSerchRec;
  FileAttrs : Integer;
begin
  if FindFirst(P, FileAttrs, sr) = 0 then begin
    repeat
       :
    until FindNext(sr) <> 0;
  end; //if
  FindClose(sr);


igy  2010-09-25 23:46:28  No: 39216

>  sr : TSerchRec;

TSerchRec は何ですか?(TSearchRecの間違い?)

>  FileAttrs : Integer;
>begin
>  if FindFirst(P, FileAttrs, sr) = 0 then begin

FileAttrs には値が設定されていませんが、正しく動作しますか?

>処理量が多いと「システムリソースが足りません」と表示されます。

この現象は、FindFirst, FindNext を使った最小限のテストプログラムでも
起きますか?
(起きる場合、そのソースコードを挙げてみてはいかがでしょう?)


igy  2010-09-26 01:42:30  No: 39217

あと、FindClose 関数の位置を

if FindFirst(P, FileAttrs, sr) = 0 then begin
  repeat
     :
  until FindNext(sr) <> 0;
  FindClose(sr);
end; //if

のように移動した場合でも、その現象が起こりますか?


かず  2010-09-26 05:21:46  No: 39218

igyさん
sr : TSearchRec;  です。投稿時タイプミスでした。

>FileAttrs には値が設定されていませんが、正しく動作しますか?
省略しすぎました。下記のとおりです。

処理の内容は、jpg画像とExif情報を取り込みをしています。
これらの機能をしないようにしてもおきるので、FindFirstが原因ではないかと考えています。

>FindClose 関数の位置を
FindClose(sr);の位置は、Webでいろいろな意見がありました
どちらでも同じ症状です。

var
  sr : TSearchRec;
  FileAttrs : Integer;
begin
    :
  FileAttrs := faAnyFile;
  P := EditFolderShitei.Text + '\*.jpg';
  if FindFirst(P, FileAttrs, sr) = 0 then begin
    repeat
       :
    until FindNext(sr) <> 0;
  end; //if
  FindClose(sr);

----ソース-------
//---  フォルダからJpegファイルを読んでテーブルに保存      (共通ルーチン)
procedure TFormImageViewer.ShashinYomidashi;
var
  sr : TSearchRec;
  FileAttrs : Integer;
  i : Integer;
begin
  with DataModule1 do begin
    StatusBar1.Panels[1].Text := '0枚';
    Screen.Cursor := crHourGlass;
//  絞り込みダイアログボックスの初期化
    with ShiborikomiDlg do begin
      ListBoxCamera.Items.Clear;
      ListBoxGasosuu.Items.Clear;
      MaskEditSatsueibiStart.Text := DateToStr(Date);
      MaskEditSatsueibiEnd.Text := '';
    end;
    ShashinTable.Filtered := False;
    if ShashinTable.RecordCount > 0 then begin
      ShashinTable.Active := False;
      ShashinTable.EmptyTable;
      ShashinTable.Active := True;
    end;
//画像をテーブルに登録
    DCount := 1;
    FileAttrs := faAnyFile;
    P := EditFolderShitei.Text + '\*.jpg';
    if FindFirst(P, FileAttrs, sr) = 0 then begin
      repeat
        if not ((sr.Name = '..')or(sr.Name = '.'))  then begin
//        DBに追加する
          ShashinTable.Append;
          ShashinTableNo.Value := DCount;
          ShashinTableFileName.Value := sr.Name;
          ShashinTableSatsueibi.Value := '';
          ShashinTableSatsueiJikan.Value := '';
          ShashinTableSentaku.Value := False;
          P := EditFolderShitei.Text + '\' + sr.Name;
          ShashinTablePath.Value := P;
//        ---  イメージの縮小   240*160 240*180 にする
          JpegImg.LoadFromFile(P);
          Shashin.Assign(JpegImg);
          if Shashin.Width > Shashin.Height then begin
            if Shashin.Width / Shashin.Height > 1.4 then
              HSize := 160
            else
              HSize := 180;
            if Shashin.Width > 240 then
              Shashin := Stretch(Shashin, 240, HSize)   //Shrink
          end else begin
            if Shashin.Height / Shashin.Width > 1.4 then
              WSize := 120
            else
              WSize := 135;
            if Shashin.Height > 180 then
              Shashin := Stretch(Shashin, WSize, 180)      //Shrink
          end; //if
//        Exif情報があるかどうか,あれば写真情報を書き込み,なければーを書き込む
//        モデル、撮影日、撮影時間、画素数
          try
            ExifInfo1.ImageFileName := P;
            with ExifInfo1 do begin
              if IsExif(ImageFileName) = True then begin
                if Model <> '' then
                  ModelMake := Model + '  <' + Make  + '>';
                  ShashinTableModal.Value := ModelMake;
                S := Copy(DateTimeOriginalText, 1, 4) + '/' + Copy(DateTimeOriginalText, 6, 2) + '/' + Copy(DateTimeOriginalText, 9, 2);
                ShashinTableSatsueibi.Value := S;
                Satsueibi := FormatDateTime('yyyy/mm/dd', StrToDate(S));
                ShashinTableSatsueiJikan.Value := Copy(DateTimeOriginalText, 12, 8);
                Gasosuu := IntToStr(ImageWidth) + ' × ' + IntToStr(ImageLength);
                ShashinTableGasosuu.Value := Gasosuu;
//             回転角の取得
                case ExifInfo1.Orientation of
                  eoBottomRight : Kaitenkaku := '180度回転';
                  eoRightTop    : Kaitenkaku := '270度回転';
                  eoLeftBottom  : Kaitenkaku := '90度回転';
                else
                  Kaitenkaku := '';
                end;
                ShashinTableKaitenKaku.Value := Kaitenkaku;
              end;
            end;
          except
            GetFileInfo;
            ShashinTableSatsueibi.Value := FormatDateTime('yyyy/mm/dd',ADateTime);
            ShashinTableSatsueiJikan.Value := FormatDateTime('hh:nn:ss',ADateTime);
            ShashinTableModal.Value := '-';
            ShashinTableGasosuu.Value  := IntToStr(JpegImg.Width) + ' × ' + IntToStr(JpegImg.Height);
          end;   //try
//        テーブルに縮小Bitmapを書き込む
          ShashinTableShashin.Assign(Shashin);
//        絞り込みリスト作成   撮影日、カメラの機種  画素数  
          with ShiborikomiDlg do begin
            if MaskEditSatsueibiStart.Text > Satsueibi then
               MaskEditSatsueibiStart.Text := Satsueibi;
            if MaskEditSatsueibiEnd.Text < Satsueibi then
               MaskEditSatsueibiEnd.Text := Satsueibi;
//          カメラのモデルをリストに登録済みかどうか見て追加する
            i := 1;
            while (i <= ListBoxCamera.Items.Count)and(ModelMake <> ListBoxCamera.Items[i - 1]) do
              Inc(i);
            if (i > ListBoxCamera.Items.Count)and(Length(ModelMake) > 5) then
              ListBoxCamera.Items.Add(ShashinTableModal.Value);
//          画素数をリストに登録済みかどうか見て追加する
            i := 1;
            while (i <= ListBoxGasosuu.Items.Count)and(Gasosuu <> ListBoxGasosuu.Items[i - 1]) do
              Inc(i);
            if (i > ListBoxGasosuu.Items.Count)and(Length(Gasosuu) > 5) then
              ListBoxGasosuu.Items.Add(ShashinTableGasosuu.Value);
          end;
          ShashinTable.Post;
          Inc(DCount);
        end;  //if not
      until FindNext(sr) <> 0;
    end; //if
    FindClose(sr);
    ShashinTable.First;
    StatusBar1.Panels[1].Text := FormatFloat('#,##0枚', DCount - 1);
    Screen.Cursor := crDefault;
  end;
end;


igy  2010-09-26 05:50:50  No: 39219

>これらの機能をしないようにしてもおきるので、FindFirstが原因ではないかと考えています。

では、実際に以下のコードにした場合、エラーは表示しますか?

procedure TFormImageViewer.ShashinYomidashi;
var
  sr : TSearchRec;
  FileAttrs : Integer;
  i : Integer;
begin
    StatusBar1.Panels[1].Text := '0枚';
    Screen.Cursor := crHourGlass;
    DCount := 1;
    FileAttrs := faAnyFile;
    P := EditFolderShitei.Text + '\*.jpg';
    if FindFirst(P, FileAttrs, sr) = 0 then begin
      repeat
        if not ((sr.Name = '..')or(sr.Name = '.'))  then begin
          Inc(DCount);
        end;  //if not
      until FindNext(sr) <> 0;
      FindClose(sr);
    end; //if
    StatusBar1.Panels[1].Text := FormatFloat('#,##0枚', DCount - 1);
    Screen.Cursor := crDefault;
end;


かず  2010-09-26 06:27:38  No: 39220

igyさん
指定されたソースでは、「システムリソースが足りません」は表示されないし、タスクマネージャーでもメモリ消費は起きませんでした。
ありがとうございました。
もう一度あたり直しです。


かず  2010-09-26 06:53:16  No: 39221

「システムリソースが足りません」を起こす箇所が判明しました。
今まで調べた箇所とは別の場所でイメージの縮小   240*160 240*180をしている場所でした。
ここではDHGL1.3でイメージ処理をしています。

お騒がせしました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加