Changed behaviour for filestream with Windows 7?

delphi, delphi-2007

Solution

Quick shot: When you have a file that is written quite often like a log file, you should disable the indexing of the contents for that file. Otherwise the Windows indexer service will constantly reindex that file and meanwhile blocking any other request.

You can find the context indexing attribute under "file properties" - "extended attributes".

IMHO it was not the best decision from Microsoft to enable the content indexing in Windows 7 by default.

Problem

I have written a utility that search logfiles for exceptions and it have worked fine with Vista 64 bits. Now I have upgraded to Windows 7 64 bits and it could sometimes hang forever when reading a filestream. I think it hangs only if the log file is active and the user write to it. But this works fine before as I use fmShareDenyNone flag. I use Delphi 2007. Any idea what I could change to make this work ? Here is the whole method that search directories for logfiles: ``` procedure TfrmMain.Refresh; var FileData : TSearchRec; // Used for the file searching. Contains data of the file vPos, i, PathIndex : Integer; vCurrentFile: TStringList; vDate: TDateTime; vFileStream: TFileStream; begin tvMain.DataController.RecordCount := 0; vCurrentFile := TStringList.Create; memCallStack.Clear; try for PathIndex := 0 to fPathList.Count - 1 do // Loop 0. This loops until all directories are searched through begin if (FindFirst (fPathList[PathIndex] + '\*.log', faAnyFile, FileData) = 0) then repeat // Loop 1. This loops while there are .log files in Folder (CurrentPath) vDate := FileDateToDateTime(FileData.Time); if chkLogNames.Items[PathIndex].Checked and FileDateInInterval(vDate) then begin tvMain.BeginUpdate; // To speed up the grid - delays the guichange until EndUpdate fPathPlusFile := fPathList[PathIndex] + '\' + FileData.Name; vFileStream := TFileStream.Create(fPathPlusFile, fmShareDenyNone); vCurrentFile.LoadFromStream(vFileStream); fUser := FindDataInRow(vCurrentFile[0], 'User'); // FindData Returns the string after 'User' until ' ' fComputer := FindDataInRow(vCurrentFile[0], 'Computer'); // FindData Returns the string after 'Computer' until ' ' Application.ProcessMessages; // Give some priority to the User Interface if not CancelForm.IsCanceled then begin CancelForm.lblLogFile.Caption := fPathPlusFile; if rdException.Checked then for i := 0 to vCurrentFile.Count - 1 do begin vPos := AnsiPos(MainExceptionToFind, vCurrentFile[i]); if vPos > 0 then UpdateView(vCurrentFile[i], i, MainException); vPos := AnsiPos(ExceptionHintToFind, vCurrentFile[i]); if vPos > 0 then UpdateView(vCurrentFile[i], i, HintException); end else if rdOtherText.Checked then for i := 0 to vCurrentFile.Count - 1 do begin vPos := AnsiPos(txtTextToSearch.Text, vCurrentFile[i]); if vPos > 0 then UpdateView(vCurrentFile[i], i, TextSearch) end end; vFileStream.Destroy; tvMain.EndUpdate; // Now the Gui can be updated end; until(FindNext(FileData) <> 0) or (CancelForm.IsCanceled); // End Loop 1 end; // End Loop 0 finally FreeAndNil(vCurrentFile); end; end; ```

Original source