2010-01-29 15 views
3

J'ai écrit un utilitaire qui recherche les fichiers journaux pour les exceptions et il a bien fonctionné avec Vista 64 bits. Maintenant, j'ai mis à niveau vers Windows 7 64 bits et il pourrait parfois être suspendu à jamais lors de la lecture d'un flux de fichiers. Je pense que cela ne se bloque que si le fichier journal est actif et que l'utilisateur y écrit. Mais cela fonctionne bien avant que j'utilise le drapeau fmShareDenyNone. J'utilise Delphi 2007. Avez-vous une idée de ce que je pourrais changer pour que cela fonctionne?Comportement modifié pour filestream avec Windows 7?

Voici toute la méthode qui recherche dans les répertoires pour les fichiers journaux:

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; 
+1

La première chose que vous devriez faire ici est de refactoriser le code de l'interface utilisateur de la logique actuelle. Débarrassez-vous de tvMain, UpdateView, memCallStack, Application.ProcessMessages, CancelForm, FindDataInRow. Le code résultant devrait être beaucoup plus court et plus facile à reproduire. –

+0

Oui, je suis d'accord là-dessus. Cela a commencé comme un outil rapide et sale au lieu de chercher des logdirs manuellement. Mais il a évolué pour être utile à la fois pour les développeurs et le support. –

+2

Lorsque votre application semble se bloquer, appuyez sur le bouton "pause" dans le débogueur pour savoir exactement où il est accroché. Vous avez dit qu'il se bloque pendant la lecture d'un flux de fichiers, mais vous parlez du mode de partage. Si le partage était plus pertinent, alors votre programme se bloquerait en * ouvrant * le fichier, pas en le lisant. La pile d'appel de votre programme en pause vous dira où cela se produit. –

Répondre

5

tir rapide: Lorsque vous avez un fichier qui est écrit assez souvent comme un fichier journal, vous devez désactiver l'indexation du contenu pour que fichier. Sinon, le service d'indexation de Windows réindexe constamment ce fichier et bloque toute autre demande.

Vous pouvez trouver l'attribut d'indexation de contexte sous "Propriétés du fichier" - "Attributs étendus". IMHO ce n'était pas la meilleure décision de Microsoft pour activer l'indexation de contenu dans Windows 7 par défaut.

+0

Les fichiers journaux sont accessibles avec le partage de fichiers et se trouvent sur un serveur avec Windows Server 2003. Je l'ai vérifié et le serveur dispose d'une fonction d'indexation pour le répertoire des journaux. Je l'éteins pour voir s'il y a des améliorations. Merci pour le conseil! –

+0

Par défaut, Windows parcourt uniquement les fichiers de l'utilisateur (je devais entrer et activer manuellement tous les autres emplacements, je souhaite que Microsoft active l'indexation de contenu par défaut) - il ne parcourt pas par défaut un dossier écrit par un développeur un fichier journal à. –