You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 rivejä
5.6 KiB

  1. unit uvfsFolder;
  2. interface
  3. uses
  4. SysUtils, Classes, uvfsManager;
  5. type
  6. { TvfsFileSystemFolder }
  7. TvfsFileSystemFolder = class(TvfsProvider)
  8. private
  9. FRoot: string;
  10. function ExpandPath(P:string): string;
  11. procedure DeleteEmptyDir(aDir: String);
  12. public
  13. constructor Create(const FileSpec:string; const ExtendedData: string=''); override;
  14. class function StorageName: string; override;
  15. function StorageGetFileSpec: string; override;
  16. // ACHTUNG: FileInfo.Size wird mit einem Integer gefüllt. Bei Dateien > 2GB aufpassen!
  17. function GetFileInfo(const FileName: string; out FileInfo: TvfsFileInfo): Boolean; override;
  18. function Open(const FileName: string; const OpenMode: TvfsFileOpenMode; out Stream: IStreamHandle): boolean; override;
  19. function Rename(const OldName, NewName: string): boolean; override;
  20. function Delete(const aName: String): boolean; override;
  21. procedure DirectoryIndex(AddFunction: TvfsDirectoryAddFunc; List: TvfsDirectoryList; Path: string; Subdirs: boolean); override;
  22. function Root: string;
  23. end;
  24. implementation
  25. { TvfsFileSystemFolder }
  26. constructor TvfsFileSystemFolder.Create(const FileSpec: string; const ExtendedData: string);
  27. begin
  28. inherited;
  29. FRoot:= vfsSystemPathDelim(FileSpec);
  30. end;
  31. class function TvfsFileSystemFolder.StorageName: string;
  32. begin
  33. Result:= 'folder';
  34. end;
  35. function TvfsFileSystemFolder.StorageGetFileSpec: string;
  36. begin
  37. Result:= Self.Root;
  38. end;
  39. procedure TvfsFileSystemFolder.DirectoryIndex(AddFunction: TvfsDirectoryAddFunc; List: TvfsDirectoryList; Path: string; Subdirs: boolean);
  40. procedure FindFiles(sRoot, sPfad: String);
  41. var
  42. Rec:TSearchRec;
  43. s: string;
  44. a: TvfsDirectoryEntry;
  45. begin
  46. if sPfad>'' then
  47. sPfad:= IncludeTrailingPathDelimiter(sPfad);
  48. if FindFirst(sRoot+sPfad+'*', faAnyFile,Rec)=0 then
  49. repeat
  50. if (Rec.Name<>'.') and (Rec.Name<>'..') then begin
  51. s:= sPfad+Rec.Name;
  52. a:= TvfsDirectoryEntry.Create;
  53. a.FileInfo.Size:= Rec.Size;
  54. a.FileInfo.Attributes:= Rec.Attr;
  55. a.FileInfo.ModDate:= FileDateToDateTime(Rec.Time);
  56. if (Rec.Attr and faDirectory = faDirectory) then begin
  57. AddFunction(IncludeTrailingPathDelimiter(s), a, List);
  58. if Subdirs then
  59. FindFiles(sRoot, s);
  60. end else
  61. AddFunction(s, a, List);
  62. end;
  63. until FindNext(Rec)<>0;
  64. Findclose(Rec);
  65. end;
  66. begin
  67. FindFiles(IncludeTrailingPathDelimiter(FRoot),Path);
  68. end;
  69. function TvfsFileSystemFolder.ExpandPath(P: string): string;
  70. begin
  71. Result:= vfsSystemPathDelim(IncludeTrailingPathDelimiter(FRoot)+P);
  72. end;
  73. procedure TvfsFileSystemFolder.DeleteEmptyDir(aDir: String);
  74. function FileCount(aDir: String): Integer;
  75. var
  76. sr: TSearchRec;
  77. found: Integer;
  78. begin
  79. result := 0;
  80. if (Length(aDir) > 0) and (aDir[Length(aDir)] <> '\') then
  81. aDir := aDir + '\';
  82. found := FindFirst(aDir+'*.*', faAnyFile, sr);
  83. while found = 0 do begin
  84. if (sr.Name <> '.') and (sr.Name <> '..') then
  85. inc(result);
  86. found := FindNext(sr);
  87. end;
  88. FindClose(sr);
  89. end;
  90. begin
  91. while DirectoryExists(aDir) and (FileCount(aDir) = 0) do begin
  92. RemoveDir(aDir);
  93. if (Length(aDir) > 0) and (aDir[Length(aDir)] = '\') then
  94. System.Delete(aDir, Length(aDir), 1);
  95. aDir := ExtractFilePath(aDir);
  96. end;
  97. end;
  98. function TvfsFileSystemFolder.GetFileInfo(const FileName: String; out FileInfo: TvfsFileInfo): Boolean;
  99. var
  100. sr: TSearchRec;
  101. begin
  102. Result:= FindFirst(ExpandPath(FileName),faAnyFile, sr) = 0;
  103. try
  104. if Result then begin
  105. FileInfo.Size:= sr.Size;
  106. FileInfo.Attributes:= sr.Attr;
  107. FileInfo.ModDate:= FileDateToDateTime(sr.Time);
  108. end;
  109. finally
  110. FindClose(sr);
  111. end;
  112. end;
  113. function TvfsFileSystemFolder.Open(const FileName: string; const OpenMode: TvfsFileOpenMode; out Stream: IStreamHandle): boolean;
  114. var
  115. fs: TFileStream;
  116. mode: word;
  117. begin
  118. Stream:= nil;
  119. Result:= false;
  120. try
  121. case OpenMode of
  122. omCreateAlways: mode:= fmCreate;
  123. else
  124. begin
  125. if FileExists(ExpandPath(FileName)) then
  126. case OpenMode of
  127. omReadOnly: mode:= fmOpenRead or fmShareDenyWrite;
  128. omReadWrite,
  129. omReadWriteCreate: mode:= fmOpenReadWrite;
  130. end
  131. else
  132. case OpenMode of
  133. omReadOnly,
  134. omReadWrite: exit;
  135. omReadWriteCreate: mode:= fmCreate;
  136. end;
  137. end;
  138. end;
  139. if (mode and fmCreate) > 0 then
  140. ForceDirectories(ExtractFilePath(ExpandPath(FileName)));
  141. try
  142. fs:= TFileStream.Create(ExpandPath(FileName), mode);
  143. except
  144. fs := nil;
  145. end;
  146. Result:= Assigned(fs);
  147. if Result then begin
  148. if OpenMode = omReadOnly then
  149. Stream:= TvfsStreamHandleRead.Create(fs)
  150. else
  151. Stream:= TvfsStreamHandleWrite.Create(fs, nil, nil, 0);
  152. end;
  153. except
  154. FreeAndNil(fs);
  155. raise;
  156. end;
  157. end;
  158. function TvfsFileSystemFolder.Rename(const OldName, NewName: string): boolean;
  159. var
  160. oldFile, newFile: String;
  161. begin
  162. oldFile := ExpandPath(OldName);
  163. newFile := ExpandPath(NewName);
  164. result := ForceDirectories(ExtractFilePath(newFile));
  165. if result then begin
  166. Result:= RenameFile(oldFile, newFile);
  167. DeleteEmptyDir(ExtractFilePath(oldFile));
  168. end;
  169. end;
  170. function TvfsFileSystemFolder.Delete(const aName: String): boolean;
  171. var
  172. filename: String;
  173. begin
  174. filename := ExpandPath(aName);
  175. result := DeleteFile(filename);
  176. if not result then
  177. result := RemoveDir(filename);
  178. DeleteEmptyDir(ExtractFilePath(filename));
  179. end;
  180. function TvfsFileSystemFolder.Root: string;
  181. begin
  182. Result:= FRoot;
  183. end;
  184. initialization
  185. VFSManager.RegisterProvider(TvfsFileSystemFolder);
  186. end.