View Issue Details

IDProjectCategoryView StatusLast Update
0001387Double CommanderFile operationspublic2020-11-30 14:49
Reportercordylus Assigned ToAlexx2000  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
ProjectionnoneETAnone 
OS VersionWindows XP 
Target Version0.8.0Fixed in Version0.8.0 
Summary0001387: Поиск по файлам с проверкой содержимого изменяет access time всех проверяемых файлов
DescriptionПроводник Windows, например, работает тоньше.

https://stackoverflow.com/questions/5663766/avoid-updating-last-accessed-date-time-when-reading-a-file

P.S. access time лучше проверять через меню Файлы - Изменить аттрибуты - "Открыт", т.к. открытие свойств файла само по себе изменяет этот параметр и при повторном открытии свойств будет уже текущая дата.
TagsNo tags attached.
Attached Files
bug1387-windows.patch (3,799 bytes)   
Index: components/doublecmd/dcclassesutf8.pas
===================================================================
--- components/doublecmd/dcclassesutf8.pas	(revision 7565)
+++ components/doublecmd/dcclassesutf8.pas	(working copy)
@@ -28,7 +28,11 @@
 interface
 
 uses
-  Classes, RtlConsts, SysUtils, IniFiles;
+  Classes, RtlConsts, SysUtils, IniFiles
+  {$IF DEFINED(MSWINDOWS)}
+  , Windows
+  {$ENDIF}
+  ;
 
 type
   { TFileStreamEx class }
@@ -39,6 +43,7 @@
     FFileName: String;
   public
     constructor Create(const AFileName: String; Mode: LongWord);
+    constructor Create(const AFileName: String; Mode: LongWord; PreserveATime: Boolean);
     destructor Destroy; override;
     function Flush: Boolean;
     function Read(var Buffer; Count: LongInt): LongInt; override;
@@ -76,7 +81,7 @@
 
 constructor TFileStreamEx.Create(const AFileName: String; Mode: LongWord);
 begin
-  if (Mode and fmCreate) <> 0 then
+  if (Mode and fmCreate {$IFDEF MSWINDOWS}and not FILE_WRITE_ATTRIBUTES{$ENDIF}) <> 0 then
     begin
       FHandle:= mbFileCreate(AFileName, Mode);
       if FHandle = feInvalidHandle then
@@ -85,7 +90,7 @@
         inherited Create(FHandle);
     end
   else
-    begin 
+    begin
       FHandle:= mbFileOpen(AFileName, Mode);
       if FHandle = feInvalidHandle then
         raise EFOpenError.CreateFmt(SFOpenError, [AFilename])
@@ -95,6 +100,24 @@
   FFileName:= AFileName;
 end;
 
+constructor TFileStreamEx.Create(const AFileName: String; Mode: LongWord; PreserveATime: Boolean);
+{$IFDEF MSWINDOWS}
+const ft: TFileTime = ( dwLowDateTime: $FFFFFFFF; dwHighDateTime: $FFFFFFFF; );
+begin
+  if PreserveATime then
+    begin
+      Create(AFileName, Mode or FILE_WRITE_ATTRIBUTES);
+      SetFileTime(FHandle, nil, @ft, @ft);
+    end
+  else
+    Create(AFileName, Mode);
+end;
+{$ELSE}
+begin
+  Create(AFileName, Mode);
+end;
+{$ENDIF}
+
 destructor TFileStreamEx.Destroy;
 begin
   inherited Destroy;
@@ -216,7 +239,11 @@
     try
       GetStrings(slLines);
       slLines.SaveToFile(FileName);
+      {$IF DEFINED(MSWINDOWS)}
+      PBoolean(@Dirty)^:= Byte(False);
+      {$ELSE}
       PBoolean(@Dirty)^:= False;
+      {$ENDIF}
     finally
       slLines.Free;
     end;
Index: components/doublecmd/dcosutils.pas
===================================================================
--- components/doublecmd/dcosutils.pas	(revision 7565)
+++ components/doublecmd/dcosutils.pas	(working copy)
@@ -567,7 +567,7 @@
 function mbFileOpen(const FileName: String; Mode: LongWord): System.THandle;
 {$IFDEF MSWINDOWS}
 begin
-  Result:= CreateFileW(PWideChar(UTF16LongName(FileName)), AccessModes[Mode and 3],
+  Result:= CreateFileW(PWideChar(UTF16LongName(FileName)), AccessModes[Mode and 3] or (Mode and $180),
                        ShareModes[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL, OpenFlags[(Mode shr 16) and 3]);
 end;
Index: src/ufindthread.pas
===================================================================
--- src/ufindthread.pas	(revision 7565)
+++ src/ufindthread.pas	(working copy)
@@ -258,7 +258,7 @@
   // Simple regular expression search (don't work for very big files)
   if bRegExp then
   begin
-    fs := TFileStreamEx.Create(sFileName, fmOpenRead or fmShareDenyNone);
+    fs := TFileStreamEx.Create(sFileName, fmOpenRead or fmShareDenyNone, True);
     try
       if fs.Size = 0 then Exit;
       {$PUSH}{$R-}
@@ -296,7 +296,7 @@
   if sDataLength > BufferSize then
     raise Exception.Create(rsMsgErrSmallBuf);
 
-  fs := TFileStreamEx.Create(sFileName, fmOpenRead or fmShareDenyNone);
+  fs := TFileStreamEx.Create(sFileName, fmOpenRead or fmShareDenyNone, True);
   try
     if sDataLength > fs.Size then // string longer than file, cannot search
       Exit;
bug1387-windows.patch (3,799 bytes)   
Fixed in Revision7714, 7723
Operating system
Widgetset
Architecture

Relationships

related to 0002008 closedcordylus Не работает поиск в некоторых файлах 

Activities

cordylus

2017-05-17 18:13

developer   ~0002238

Реализовал для Windows. Для Linux должно быть несложно доделать, там нужно O_NOATIME передавать.

cordylus

2017-05-20 02:08

developer   ~0002243

Last edited: 2017-05-20 02:12

Нужно ещё для генерации эскизов это включить - передавать True в TFileStreamEx.Create.

Issue History

Date Modified Username Field Change
2016-05-21 21:02 cordylus New Issue
2017-05-17 17:04 cordylus File Added: bug1387-windows.patch
2017-05-17 18:13 cordylus Note Added: 0002238
2017-05-19 23:48 Alexx2000 Target Version => 0.8.0
2017-05-19 23:57 Alexx2000 Status new => acknowledged
2017-05-20 02:08 cordylus Note Added: 0002243
2017-05-20 02:12 cordylus Note Edited: 0002243
2017-07-29 18:11 Alexx2000 Fixed in Revision => 7714
2017-07-29 18:11 Alexx2000 Status acknowledged => resolved
2017-07-29 18:11 Alexx2000 Resolution open => fixed
2017-07-29 18:11 Alexx2000 Assigned To => Alexx2000
2017-08-12 12:09 Alexx2000 Fixed in Revision 7714 => 7714, 7723
2017-08-12 12:09 Alexx2000 Fixed in Version => 0.8.0
2018-01-29 01:26 cordylus Relationship added related to 0002008
2020-11-30 14:49 Alexx2000 Status resolved => closed