home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / unity / d56 / FNDUTL.ZIP / System / cFileUtils.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-10-29  |  12.1 KB  |  341 lines

  1. {$INCLUDE ..\cDefines.inc}
  2. unit cFileUtils;
  3.  
  4. {                                                                              }
  5. {                        File utility functions v3.01                          }
  6. {                                                                              }
  7. {         This unit is copyright ⌐ 2002 by David Butler (david@e.co.za)        }
  8. {                                                                              }
  9. {                  This unit is part of Delphi Fundamentals.                   }
  10. {                  Its original file name is cFileUtils.pas                    }
  11. {       The latest version is available from the Fundamentals home page        }
  12. {                     http://fundementals.sourceforge.net/                     }
  13. {                                                                              }
  14. {                I invite you to use this unit, free of charge.                }
  15. {        I invite you to distibute this unit, but it must be for free.         }
  16. {             I also invite you to contribute to its development,              }
  17. {             but do not distribute a modified copy of this file.              }
  18. {                                                                              }
  19. {          A forum is available on SourceForge for general discussion          }
  20. {             http://sourceforge.net/forum/forum.php?forum_id=2117             }
  21. {                                                                              }
  22. { Revision history:                                                            }
  23. {   01/06/2002  3.01  Created cFileUtils from cSysUtils.                       }
  24. {                                                                              }
  25. interface
  26.  
  27. uses
  28.   // Delphi
  29.   SysUtils;
  30.  
  31.  
  32.  
  33. {                                                                              }
  34. { Path functions                                                               }
  35. {                                                                              }
  36. const
  37.   {$IFDEF OS_UNIX}
  38.   PathSeparator = '/';
  39.   {$ENDIF}
  40.   {$IFDEF OS_MSWIN}
  41.   PathSeparator = '\';
  42.   {$ENDIF}
  43.  
  44. Function  UnixPathToWindowsPath (const Path : String) : String;
  45. Function  WindowsPathToUnixPath (const Path : String) : String;
  46. Function  StringToValidFileName (const S : String) : String;
  47.  
  48. Function  PathWithSlashSuffix (const Path : String; const PathSep : Char = PathSeparator) : String;
  49. Function  PathWithoutSlashSuffix (const Path : String; const PathSep : Char = PathSeparator) : String;
  50. Function  PathLeftElement (const Path : String; const PathSep : Char = PathSeparator) : String;
  51. Function  PathRightElement (const Path : String; const PathSep : Char = PathSeparator) : String;
  52. Function  PathWithoutLeftElement (const Path : String; const PathSep : Char = PathSeparator) : String;
  53. Function  PathWithoutRightElement (const Path : String; const PathSep : Char = PathSeparator) : String;
  54. Procedure PathSplitLeftElement (const Path : String; const PathSep : Char;
  55.           var LeftElement, RightElement : String);
  56. Procedure PathSplitRightElement (const Path : String; const PathSep : Char;
  57.           var LeftElement, RightElement : String);
  58.  
  59. Function  MergeFilePath (const Path : String; const FileName : String;
  60.           const PathSep : Char = PathSeparator) : String;
  61. Function  IsAbsolutePath (const Path : String) : Boolean;
  62. Function  ExpandPath (const Path, DefaultPath : String) : String;
  63.  
  64.  
  65.  
  66. {                                                                              }
  67. { File operations                                                              }
  68. {   MoveFile will first attempt a rename, then a copy&delete.                  }
  69. {                                                                              }
  70. type
  71.   EFileError = class (Exception);
  72.  
  73. Function  GetFileSize (const FileName : String) : Int64;
  74. Function  GetFileDateTime (const FileName : String) : TDateTime;
  75. Function  GetFirstFileNameMatching (const FileMask : String) : String;
  76. Function  FileHasAttr (const FileName : String; const Attr : Word) : Boolean;
  77. Procedure CopyFile (const FileName, DestName : String);
  78. Procedure MoveFile (const FileName, DestName : String);
  79. Function  DeleteFiles (const FileMask : String) : Boolean;
  80.  
  81.  
  82.  
  83. implementation
  84.  
  85. uses
  86.   // Fundamentals
  87.   cStrings;
  88.  
  89.  
  90.  
  91. {                                                                              }
  92. { Path functions                                                               }
  93. {                                                                              }
  94. Function UnixPathToWindowsPath (const Path : String) : String;
  95.   Begin
  96.     Result := Replace ('/', '\', Replace (['\', ':', '"', '<', '>', '|'], '_', Path));
  97.   End;
  98.  
  99. { Network path:  \\      --->   /                                              }
  100. { Device path:   \\.\    --->   /                                              }
  101. { Drive letter:  X:      --->   X/                                             }
  102. Function WindowsPathToUnixPath (const Path : String) : String;
  103.   Begin
  104.     Result := Path;
  105.     if Length (Result) >= 2 then
  106.       if Result [2] = ':' then // drive letter
  107.         Result [2] := '/' else
  108.       if (Result [1] = '\') and (Result [2] = '\') then
  109.         if (Length (Result) >= 3) and (Result [3] = '.') then
  110.           Delete (Result, 1, 3) else    // device path
  111.           Delete (Result, 1, 1);        // network path
  112.     Result := Replace ('\', '/', Replace (['/', ':', '"', '<', '>', '|'], '_', Path));
  113.   End;
  114.  
  115. Function StringToValidFileName (const S : String) : String;
  116.   Begin
  117.     Result := Replace (['\', '/', ':', '>', '<', '*', '?'], '_', S);
  118.   End;
  119.  
  120. Function PathWithSlashSuffix (const Path : String; const PathSep : Char) : String;
  121.   Begin
  122.     Result := Path;
  123.     if Result = '' then
  124.       exit;
  125.     EnsureSuffix (Result, PathSep);
  126.   End;
  127.  
  128. Function PathWithoutSlashSuffix (const Path : String; const PathSep : Char) : String;
  129.   Begin
  130.     Result := Path;
  131.     EnsureNoSuffix (Result, PathSep);
  132.   End;
  133.  
  134. Function PathLeftElement (const Path : String; const PathSep : Char) : String;
  135.   Begin
  136.     Result := CopyBefore (Path, PathSep, True);
  137.   End;
  138.  
  139. Function PathRightElement (const Path : String; const PathSep : Char) : String;
  140.   Begin
  141.     Result := CopyFrom (Path, Pos (PathSep, Path, [foReverse]) + 1);
  142.   End;
  143.  
  144. Function PathWithoutLeftElement (const Path : String; const PathSep : Char) : String;
  145.   Begin
  146.     Result := CopyAfter (Path, PathSep, False);
  147.   End;
  148.  
  149. Function PathWithoutRightElement (const Path : String; const PathSep : Char) : String;
  150.   Begin
  151.     Result := CopyBefore (Path, PathSep, False, [foReverse]);
  152.   End;
  153.  
  154. Procedure PathSplitLeftElement (const Path : String; const PathSep : Char; var LeftElement, RightElement : String);
  155.   Begin
  156.     Split (Path, PathSep, LeftElement, RightElement, True, splitCenter, []);
  157.   End;
  158.  
  159. Procedure PathSplitRightElement (const Path : String; const PathSep : Char; var LeftElement, RightElement : String);
  160.   Begin
  161.     Split (Path, PathSep, LeftElement, RightElement, False, splitCenter, [foReverse]);
  162.     if (LeftElement = '') and (RightElement = '') then
  163.       RightElement := Path;
  164.   End;
  165.  
  166. Function MergeFilePath (const Path : String; const FileName : String; const PathSep : Char) : String;
  167.   Begin
  168.     if Path = '' then
  169.       Result := FileName else
  170.       begin
  171.         Result := Path;
  172.         EnsureSuffix (Result, PathSep);
  173.         Result := Result + FileName;
  174.       end;
  175.   End;
  176.  
  177. Function ExpandPath (const Path, DefaultPath : String) : String;
  178.   Begin
  179.     if Path = '' then
  180.       Result := DefaultPath else
  181.       Result := PathWithSlashSuffix (Path);
  182.     if Result <> '' then
  183.       Result := ExpandFileName (Result);
  184.   End;
  185.  
  186. Function IsAbsolutePath (const Path : String) : Boolean;
  187. var L : Integer;
  188.   Begin
  189.     L := Length (Path);
  190.     if L = 0 then
  191.       Result := False else
  192.       if Path [1] = '\' then
  193.         Result := True else
  194.         if L = 1 then
  195.           Result := False else
  196.           if Path [2] = ':' then
  197.             Result := True else // c:xxx considered absolute
  198.             Result := False;
  199.   End;
  200.  
  201.  
  202.  
  203. {                                                                              }
  204. { File operations                                                              }
  205. {                                                                              }
  206. Function GetFileSize (const FileName : String) : Int64;
  207. var SRec : TSearchRec;
  208.   Begin
  209.     if FindFirst (FileName, faAnyFile, SRec) <> 0 then
  210.       Result := -1 else
  211.       begin
  212.         {$IFDEF MSWINDOWS}
  213.         {$WARNINGS OFF}
  214.         Int64Rec (Result).Lo := SRec.FindData.nFileSizeLow;
  215.         Int64Rec (Result).Hi := SRec.FindData.nFileSizeHigh;
  216.         {$IFDEF DEBUG}{$WARNINGS ON}{$ENDIF}
  217.         {$ELSE}
  218.         Result := SRec.Size;
  219.         {$ENDIF}
  220.         FindClose (SRec);
  221.       end;
  222.   End;
  223.  
  224. Function GetFileDateTime (const FileName : String) : TDateTime;
  225. var Age : LongInt;
  226.   Begin
  227.     Age := FileAge (FileName);
  228.     if Age = -1 then
  229.       Result := 0 else
  230.       Result := FileDateToDateTime (Age);
  231.   End;
  232.  
  233. Function GetFirstFileNameMatching (const FileMask : String) : String;
  234. var SRec : TSearchRec;
  235.   Begin
  236.     Result := '';
  237.     if FindFirst (FileMask, faAnyFile, SRec) = 0 then
  238.       try
  239.         Repeat
  240.           if SRec.Attr and faDirectory = 0 then
  241.             begin
  242.               Result := ExtractFilePath (FileMask) + SRec.Name;
  243.               exit;
  244.             end;
  245.         Until FindNext (SRec) <> 0;
  246.       finally
  247.         FindClose (SRec);
  248.       end;
  249.   End;
  250.  
  251. {$WARN SYMBOL_PLATFORM OFF}
  252. Function FileHasAttr (const FileName : String; const Attr : Word) : Boolean;
  253. var A : Integer;
  254.   Begin
  255.     A := FileGetAttr (FileName);
  256.     Result := (A >= 0) and (A and Attr <> 0);
  257.   End;
  258.  
  259. Procedure CopyFile (const FileName, DestName : String);
  260. var
  261.   CopyBuffer   : Pointer;
  262.   BytesCopied  : Longint;
  263.   Source, Dest : Integer;
  264.   Destination  : TFileName;
  265. const
  266.   ChunkSize = 8192;
  267.  
  268.   Begin
  269.     Destination := ExpandFileName (DestName);
  270.     if FileHasAttr (Destination, faDirectory) then // if destination is a directory, append file name
  271.       Destination := Destination + '\' + ExtractFileName (FileName);
  272.     GetMem (CopyBuffer, ChunkSize);
  273.     try
  274.       Source := FileOpen (FileName, fmShareDenyWrite);
  275.       if Source < 0 then
  276.         raise EFileError.CreateFmt ('Can not open file %s', [FileName]);
  277.       try
  278.         Dest := FileCreate (Destination);
  279.         if Dest < 0 then
  280.           raise EFileError.CreateFmt('Can not create file %s', [Destination]);
  281.         try
  282.           Repeat
  283.             BytesCopied := FileRead (Source, CopyBuffer^, ChunkSize);
  284.             if BytesCopied > 0 then
  285.               FileWrite (Dest, CopyBuffer^, BytesCopied);
  286.           Until BytesCopied < ChunkSize;
  287.         finally
  288.           FileClose (Dest);
  289.         end;
  290.       finally
  291.         FileClose (Source);
  292.       end;
  293.     finally
  294.       FreeMem (CopyBuffer, ChunkSize);
  295.     end;
  296.   End;
  297.  
  298. Procedure MoveFile (const FileName, DestName : String);
  299. var Destination : String;
  300.     Attr : Integer;
  301.   Begin
  302.     Destination := ExpandFileName (DestName);
  303.     if not RenameFile (FileName, Destination) then
  304.       begin
  305.         Attr := FileGetAttr (FileName);
  306.         if (Attr < 0) or (Attr and faReadOnly <> 0) then
  307.           raise EFileError.Create (Format ('Can not move file %s', [FileName]));
  308.         CopyFile (FileName, Destination);
  309.         DeleteFile (FileName);
  310.       end;
  311.   End;
  312.  
  313. Function DeleteFiles (const FileMask : String) : Boolean;
  314. var SRec : TSearchRec;
  315.     Path : String;
  316.   Begin
  317.     Result := FindFirst (FileMask, faAnyFile, SRec) = 0;
  318.     if not Result then
  319.       exit;
  320.     try
  321.       Path := ExtractFilePath (FileMask);
  322.       Repeat
  323.         if (SRec.Name <> '') and (SRec.Name  <> '.') and (SRec.Name <> '..') and
  324.           (SRec.Attr and (faVolumeID + faDirectory) = 0) then
  325.         begin
  326.           Result := DeleteFile (Path + SRec.Name);
  327.           if not Result then
  328.             break;
  329.         end;
  330.       Until FindNext (SRec) <> 0;
  331.     finally
  332.       FindClose (SRec);
  333.     end;
  334.   End;
  335. {$WARN SYMBOL_PLATFORM ON}
  336.  
  337.  
  338.  
  339. end.
  340.  
  341.