The Labs \ Source Viewer \ SSCLI \ System.IO \ File

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** Class:  File
  18. **
  19. **
  20. ** Purpose: A collection of methods for manipulating Files.
  21. **
  22. **        April 09,2000 (some design refactorization)
  23. **
  24. ===========================================================*/
  25. using System;
  26. using System.Security.Permissions;
  27. using PermissionSet = System.Security.PermissionSet;
  28. using Win32Native = Microsoft.Win32.Win32Native;
  29. using System.Runtime.InteropServices;
  30. using System.Security;
  31. using System.Text;
  32. using Microsoft.Win32.SafeHandles;
  33. using System.Collections;
  34. using System.Globalization;
  35. using System.Runtime.Versioning;
  36. namespace System.IO
  37. {
  38.     // Class for creating FileStream objects, and some basic file management
  39.     // routines such as Delete, etc.
  40.     [ComVisible(true)]
  41.     public static class File
  42.     {
  43.         private const int GetFileExInfoStandard = 0;
  44.        
  45.         [ResourceExposure(ResourceScope.Machine)]
  46.         [ResourceConsumption(ResourceScope.Machine)]
  47.         public static StreamReader OpenText(string path)
  48.         {
  49.             if (path == null)
  50.                 throw new ArgumentNullException("path");
  51.             return new StreamReader(path);
  52.         }
  53.        
  54.         [ResourceExposure(ResourceScope.Machine)]
  55.         [ResourceConsumption(ResourceScope.Machine)]
  56.         public static StreamWriter CreateText(string path)
  57.         {
  58.             if (path == null)
  59.                 throw new ArgumentNullException("path");
  60.             return new StreamWriter(path, false);
  61.         }
  62.        
  63.         [ResourceExposure(ResourceScope.Machine)]
  64.         [ResourceConsumption(ResourceScope.Machine)]
  65.         public static StreamWriter AppendText(string path)
  66.         {
  67.             if (path == null)
  68.                 throw new ArgumentNullException("path");
  69.             return new StreamWriter(path, true);
  70.         }
  71.        
  72.        
  73.         // Copies an existing file to a new file. An exception is raised if the
  74.         // destination file already exists. Use the
  75.         // Copy(String, String, boolean) method to allow
  76.         // overwriting an existing file.
  77.         //
  78.         // The caller must have certain FileIOPermissions. The caller must have
  79.         // Read permission to sourceFileName and Create
  80.         // and Write permissions to destFileName.
  81.         //
  82.         [ResourceExposure(ResourceScope.Machine)]
  83.         [ResourceConsumption(ResourceScope.Machine)]
  84.         public static void Copy(string sourceFileName, string destFileName)
  85.         {
  86.             Copy(sourceFileName, destFileName, false);
  87.         }
  88.        
  89.         // Copies an existing file to a new file. If overwrite is
  90.         // false, then an IOException is thrown if the destination file
  91.         // already exists. If overwrite is true, the file is
  92.         // overwritten.
  93.         //
  94.         // The caller must have certain FileIOPermissions. The caller must have
  95.         // Read permission to sourceFileName
  96.         // and Write permissions to destFileName.
  97.         //
  98.         [ResourceExposure(ResourceScope.Machine)]
  99.         [ResourceConsumption(ResourceScope.Machine)]
  100.         public static void Copy(string sourceFileName, string destFileName, bool overwrite)
  101.         {
  102.             InternalCopy(sourceFileName, destFileName, overwrite);
  103.         }
  104.        
  105.         /// <devdoc>
  106.         /// Note: This returns the fully qualified name of the destination file.
  107.         /// </devdoc>
  108.         [ResourceExposure(ResourceScope.Machine)]
  109.         [ResourceConsumption(ResourceScope.Machine)]
  110.         static internal string InternalCopy(string sourceFileName, string destFileName, bool overwrite)
  111.         {
  112.             if (sourceFileName == null || destFileName == null)
  113.                 throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), Environment.GetResourceString("ArgumentNull_FileName"));
  114.             if (sourceFileName.Length == 0 || destFileName.Length == 0)
  115.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName"));
  116.            
  117.             string fullSourceFileName = Path.GetFullPathInternal(sourceFileName);
  118.             new FileIOPermission(FileIOPermissionAccess.Read, new string[] {fullSourceFileName}, false, false).Demand();
  119.             string fullDestFileName = Path.GetFullPathInternal(destFileName);
  120.             new FileIOPermission(FileIOPermissionAccess.Write, new string[] {fullDestFileName}, false, false).Demand();
  121.            
  122.             bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite);
  123.             if (!r) {
  124.                 // Save Win32 error because subsequent checks will overwrite this HRESULT.
  125.                 int errorCode = Marshal.GetLastWin32Error();
  126.                 string fileName = destFileName;
  127.                
  128.                 if (errorCode != Win32Native.ERROR_FILE_EXISTS) {
  129.                     // For a number of error codes (sharing violation, path
  130.                     // not found, etc) we don't know if the problem was with
  131.                     // the source or dest file. Try reading the source file.
  132.                     using (SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullSourceFileName, FileStream.GENERIC_READ, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero)) {
  133.                         if (handle.IsInvalid)
  134.                             fileName = sourceFileName;
  135.                     }
  136.                    
  137.                     if (errorCode == Win32Native.ERROR_ACCESS_DENIED) {
  138.                         if (Directory.InternalExists(fullDestFileName))
  139.                             throw new IOException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_FileIsDirectory_Name"), destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName);
  140.                     }
  141.                 }
  142.                
  143.                 __Error.WinIOError(errorCode, fileName);
  144.             }
  145.            
  146.             return fullDestFileName;
  147.         }
  148.        
  149.        
  150.         // Creates a file in a particular path. If the file exists, it is replaced.
  151.         // The file is opened with ReadWrite accessand cannot be opened by another
  152.         // application until it has been closed. An IOException is thrown if the
  153.         // directory specified doesn't exist.
  154.         //
  155.         // Your application must have Create, Read, and Write permissions to
  156.         // the file.
  157.         //
  158.         [ResourceExposure(ResourceScope.Machine)]
  159.         [ResourceConsumption(ResourceScope.Machine)]
  160.         public static FileStream Create(string path)
  161.         {
  162.             return Create(path, FileStream.DefaultBufferSize, FileOptions.None);
  163.         }
  164.        
  165.         // Creates a file in a particular path. If the file exists, it is replaced.
  166.         // The file is opened with ReadWrite access and cannot be opened by another
  167.         // application until it has been closed. An IOException is thrown if the
  168.         // directory specified doesn't exist.
  169.         //
  170.         // Your application must have Create, Read, and Write permissions to
  171.         // the file.
  172.         //
  173.         [ResourceExposure(ResourceScope.Machine)]
  174.         [ResourceConsumption(ResourceScope.Machine)]
  175.         public static FileStream Create(string path, int bufferSize)
  176.         {
  177.             return Create(path, bufferSize, FileOptions.None);
  178.         }
  179.        
  180.         [ResourceExposure(ResourceScope.Machine)]
  181.         [ResourceConsumption(ResourceScope.Machine)]
  182.         public static FileStream Create(string path, int bufferSize, FileOptions options)
  183.         {
  184.             return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, options);
  185.         }
  186.        
  187.        
  188.         // Deletes a file. The file specified by the designated path is deleted.
  189.         // If the file does not exist, Delete succeeds without throwing
  190.         // an exception.
  191.         //
  192.         // On NT, Delete will fail for a file that is open for normal I/O
  193.         // or a file that is memory mapped. On Win95, the file will be
  194.         // deleted irregardless of whether the file is being used.
  195.         //
  196.         // Your application must have Delete permission to the target file.
  197.         //
  198.         [ResourceExposure(ResourceScope.Machine)]
  199.         [ResourceConsumption(ResourceScope.Machine)]
  200.         public static void Delete(string path)
  201.         {
  202.             if (path == null)
  203.                 throw new ArgumentNullException("path");
  204.            
  205.             string fullPath = Path.GetFullPathInternal(path);
  206.            
  207.             // For security check, path should be resolved to an absolute path.
  208.             new FileIOPermission(FileIOPermissionAccess.Write, new string[] {fullPath}, false, false).Demand();
  209.            
  210.             if (Environment.IsWin9X() && Directory.InternalExists(fullPath))
  211.                 // Win9x fails silently for directories.
  212.                 throw new UnauthorizedAccessException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("UnauthorizedAccess_IODenied_Path"), path));
  213.            
  214.             bool r = Win32Native.DeleteFile(fullPath);
  215.             if (!r) {
  216.                 int hr = Marshal.GetLastWin32Error();
  217.                 if (hr == Win32Native.ERROR_FILE_NOT_FOUND)
  218.                     return;
  219.                 else
  220.                     __Error.WinIOError(hr, fullPath);
  221.             }
  222.         }
  223.        
  224.        
  225.         [ResourceExposure(ResourceScope.Machine)]
  226.         [ResourceConsumption(ResourceScope.Machine)]
  227.         public static void Decrypt(string path)
  228.         {
  229.             if (path == null)
  230.                 throw new ArgumentNullException("path");
  231.            
  232.             throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_RequiresNT"));
  233.         }
  234.        
  235.         [ResourceExposure(ResourceScope.Machine)]
  236.         [ResourceConsumption(ResourceScope.Machine)]
  237.         public static void Encrypt(string path)
  238.         {
  239.             if (path == null)
  240.                 throw new ArgumentNullException("path");
  241.            
  242.             throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_RequiresNT"));
  243.         }
  244.        
  245.         // Tests if a file exists. The result is true if the file
  246.         // given by the specified path exists; otherwise, the result is
  247.         // false. Note that if path describes a directory,
  248.         // Exists will return true.
  249.         //
  250.         // Your application must have Read permission for the target directory.
  251.         //
  252.         [ResourceExposure(ResourceScope.Machine)]
  253.         [ResourceConsumption(ResourceScope.Machine)]
  254.         public static bool Exists(string path)
  255.         {
  256.             try {
  257.                 if (path == null)
  258.                     return false;
  259.                 if (path.Length == 0)
  260.                     return false;
  261.                
  262.                 path = Path.GetFullPathInternal(path);
  263.                
  264.                 new FileIOPermission(FileIOPermissionAccess.Read, new string[] {path}, false, false).Demand();
  265.                
  266.                 return InternalExists(path);
  267.             }
  268.             catch (ArgumentException) {
  269.             }
  270.             catch (NotSupportedException) {
  271.             }
  272.             // Security can throw this on ":"
  273.             catch (SecurityException) {
  274.             }
  275.             catch (IOException) {
  276.             }
  277.             catch (UnauthorizedAccessException) {
  278.             }
  279.            
  280.             return false;
  281.         }
  282.        
  283.         static internal bool InternalExists(string path)
  284.         {
  285.             Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
  286.             int dataInitialised = FillAttributeInfo(path, ref data, false, true);
  287.            
  288.             return (dataInitialised == 0) && (data.fileAttributes != -1) && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0);
  289.         }
  290.        
  291.        
  292.         [ResourceExposure(ResourceScope.Machine)]
  293.         [ResourceConsumption(ResourceScope.Machine)]
  294.         public static FileStream Open(string path, FileMode mode)
  295.         {
  296.             return Open(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.None);
  297.         }
  298.        
  299.         [ResourceExposure(ResourceScope.Machine)]
  300.         [ResourceConsumption(ResourceScope.Machine)]
  301.         public static FileStream Open(string path, FileMode mode, FileAccess access)
  302.         {
  303.             return Open(path, mode, access, FileShare.None);
  304.         }
  305.        
  306.         [ResourceExposure(ResourceScope.Machine)]
  307.         [ResourceConsumption(ResourceScope.Machine)]
  308.         public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
  309.         {
  310.             return new FileStream(path, mode, access, share);
  311.         }
  312.        
  313.         [ResourceExposure(ResourceScope.Machine)]
  314.         [ResourceConsumption(ResourceScope.Machine)]
  315.         public static void SetCreationTime(string path, DateTime creationTime)
  316.         {
  317.             SetCreationTimeUtc(path, creationTime.ToUniversalTime());
  318.         }
  319.        
  320.         [ResourceExposure(ResourceScope.Machine)]
  321.         [ResourceConsumption(ResourceScope.Machine)]
  322.         unsafe public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc)
  323.         {
  324.             SafeFileHandle handle;
  325.             using (OpenFile(path, FileAccess.Write, out handle)) {
  326.                 Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(creationTimeUtc.ToFileTimeUtc());
  327.                 bool r = Win32Native.SetFileTime(handle, &fileTime, null, null);
  328.                 if (!r) {
  329.                     int errorCode = Marshal.GetLastWin32Error();
  330.                     __Error.WinIOError(errorCode, path);
  331.                 }
  332.             }
  333.         }
  334.        
  335.         [ResourceExposure(ResourceScope.Machine)]
  336.         [ResourceConsumption(ResourceScope.Machine)]
  337.         public static DateTime GetCreationTime(string path)
  338.         {
  339.             return GetCreationTimeUtc(path).ToLocalTime();
  340.         }
  341.        
  342.         [ResourceExposure(ResourceScope.Machine)]
  343.         [ResourceConsumption(ResourceScope.Machine)]
  344.         public static DateTime GetCreationTimeUtc(string path)
  345.         {
  346.             string fullPath = Path.GetFullPathInternal(path);
  347.             new FileIOPermission(FileIOPermissionAccess.Read, new string[] {fullPath}, false, false).Demand();
  348.            
  349.             Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
  350.             int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
  351.             if (dataInitialised != 0)
  352.                 __Error.WinIOError(dataInitialised, fullPath);
  353.            
  354.             long dt = ((long)(data.ftCreationTimeHigh) << 32) | ((long)data.ftCreationTimeLow);
  355.             return DateTime.FromFileTimeUtc(dt);
  356.         }
  357.        
  358.         [ResourceExposure(ResourceScope.Machine)]
  359.         [ResourceConsumption(ResourceScope.Machine)]
  360.         public static void SetLastAccessTime(string path, DateTime lastAccessTime)
  361.         {
  362.             SetLastAccessTimeUtc(path, lastAccessTime.ToUniversalTime());
  363.         }
  364.        
  365.         [ResourceExposure(ResourceScope.Machine)]
  366.         [ResourceConsumption(ResourceScope.Machine)]
  367.         unsafe public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc)
  368.         {
  369.             SafeFileHandle handle;
  370.             using (OpenFile(path, FileAccess.Write, out handle)) {
  371.                 Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastAccessTimeUtc.ToFileTimeUtc());
  372.                 bool r = Win32Native.SetFileTime(handle, null, &fileTime, null);
  373.                 if (!r) {
  374.                     int errorCode = Marshal.GetLastWin32Error();
  375.                     __Error.WinIOError(errorCode, path);
  376.                 }
  377.             }
  378.         }
  379.        
  380.         [ResourceExposure(ResourceScope.Machine)]
  381.         [ResourceConsumption(ResourceScope.Machine)]
  382.         public static DateTime GetLastAccessTime(string path)
  383.         {
  384.             return GetLastAccessTimeUtc(path).ToLocalTime();
  385.         }
  386.        
  387.         [ResourceExposure(ResourceScope.Machine)]
  388.         [ResourceConsumption(ResourceScope.Machine)]
  389.         public static DateTime GetLastAccessTimeUtc(string path)
  390.         {
  391.             string fullPath = Path.GetFullPathInternal(path);
  392.             new FileIOPermission(FileIOPermissionAccess.Read, new string[] {fullPath}, false, false).Demand();
  393.            
  394.             Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
  395.             int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
  396.             if (dataInitialised != 0)
  397.                 __Error.WinIOError(dataInitialised, fullPath);
  398.            
  399.             long dt = ((long)(data.ftLastAccessTimeHigh) << 32) | ((long)data.ftLastAccessTimeLow);
  400.             return DateTime.FromFileTimeUtc(dt);
  401.         }
  402.        
  403.         [ResourceExposure(ResourceScope.Machine)]
  404.         [ResourceConsumption(ResourceScope.Machine)]
  405.         public static void SetLastWriteTime(string path, DateTime lastWriteTime)
  406.         {
  407.             SetLastWriteTimeUtc(path, lastWriteTime.ToUniversalTime());
  408.         }
  409.        
  410.         [ResourceExposure(ResourceScope.Machine)]
  411.         [ResourceConsumption(ResourceScope.Machine)]
  412.         unsafe public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc)
  413.         {
  414.             SafeFileHandle handle;
  415.             using (OpenFile(path, FileAccess.Write, out handle)) {
  416.                 Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastWriteTimeUtc.ToFileTimeUtc());
  417.                 bool r = Win32Native.SetFileTime(handle, null, null, &fileTime);
  418.                 if (!r) {
  419.                     int errorCode = Marshal.GetLastWin32Error();
  420.                     __Error.WinIOError(errorCode, path);
  421.                 }
  422.             }
  423.         }
  424.        
  425.         [ResourceExposure(ResourceScope.Machine)]
  426.         [ResourceConsumption(ResourceScope.Machine)]
  427.         public static DateTime GetLastWriteTime(string path)
  428.         {
  429.             return GetLastWriteTimeUtc(path).ToLocalTime();
  430.         }
  431.        
  432.         [ResourceExposure(ResourceScope.Machine)]
  433.         [ResourceConsumption(ResourceScope.Machine)]
  434.         public static DateTime GetLastWriteTimeUtc(string path)
  435.         {
  436.             string fullPath = Path.GetFullPathInternal(path);
  437.             new FileIOPermission(FileIOPermissionAccess.Read, new string[] {fullPath}, false, false).Demand();
  438.            
  439.             Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
  440.             int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
  441.             if (dataInitialised != 0)
  442.                 __Error.WinIOError(dataInitialised, fullPath);
  443.            
  444.             long dt = ((long)data.ftLastWriteTimeHigh << 32) | ((long)data.ftLastWriteTimeLow);
  445.             return DateTime.FromFileTimeUtc(dt);
  446.         }
  447.        
  448.         [ResourceExposure(ResourceScope.Machine)]
  449.         [ResourceConsumption(ResourceScope.Machine)]
  450.         public static FileAttributes GetAttributes(string path)
  451.         {
  452.             string fullPath = Path.GetFullPathInternal(path);
  453.             new FileIOPermission(FileIOPermissionAccess.Read, new string[] {fullPath}, false, false).Demand();
  454.            
  455.             Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
  456.             int dataInitialised = FillAttributeInfo(fullPath, ref data, false, true);
  457.             if (dataInitialised != 0)
  458.                 __Error.WinIOError(dataInitialised, fullPath);
  459.            
  460.             return (FileAttributes)data.fileAttributes;
  461.         }
  462.        
  463.         [ResourceExposure(ResourceScope.Machine)]
  464.         [ResourceConsumption(ResourceScope.Machine)]
  465.         public static void SetAttributes(string path, FileAttributes fileAttributes)
  466.         {
  467.             string fullPath = Path.GetFullPathInternal(path);
  468.             new FileIOPermission(FileIOPermissionAccess.Write, new string[] {fullPath}, false, false).Demand();
  469.             bool r = Win32Native.SetFileAttributes(fullPath, (int)fileAttributes);
  470.             if (!r) {
  471.                 int hr = Marshal.GetLastWin32Error();
  472.                 if (hr == ERROR_INVALID_PARAMETER || (hr == ERROR_ACCESS_DENIED && Environment.IsWin9X()))
  473.                     // Win9x returns Access denied sometimes
  474.                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs"));
  475.                 __Error.WinIOError(hr, fullPath);
  476.             }
  477.         }
  478.        
  479.        
  480.         [ResourceExposure(ResourceScope.Machine)]
  481.         [ResourceConsumption(ResourceScope.Machine)]
  482.         public static FileStream OpenRead(string path)
  483.         {
  484.             return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
  485.         }
  486.        
  487.        
  488.         [ResourceExposure(ResourceScope.Machine)]
  489.         [ResourceConsumption(ResourceScope.Machine)]
  490.         public static FileStream OpenWrite(string path)
  491.         {
  492.             return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
  493.         }
  494.        
  495.         [ResourceExposure(ResourceScope.Machine)]
  496.         [ResourceConsumption(ResourceScope.Machine)]
  497.         public static string ReadAllText(string path)
  498.         {
  499.             return ReadAllText(path, Encoding.UTF8);
  500.         }
  501.        
  502.         [ResourceExposure(ResourceScope.Machine)]
  503.         [ResourceConsumption(ResourceScope.Machine)]
  504.         public static string ReadAllText(string path, Encoding encoding)
  505.         {
  506.             using (StreamReader sr = new StreamReader(path, encoding))
  507.                 return sr.ReadToEnd();
  508.         }
  509.        
  510.         [ResourceExposure(ResourceScope.Machine)]
  511.         [ResourceConsumption(ResourceScope.Machine)]
  512.         public static void WriteAllText(string path, string contents)
  513.         {
  514.             WriteAllText(path, contents, StreamWriter.UTF8NoBOM);
  515.         }
  516.        
  517.         [ResourceExposure(ResourceScope.Machine)]
  518.         [ResourceConsumption(ResourceScope.Machine)]
  519.         public static void WriteAllText(string path, string contents, Encoding encoding)
  520.         {
  521.             using (StreamWriter sw = new StreamWriter(path, false, encoding))
  522.                 sw.Write(contents);
  523.         }
  524.        
  525.         [ResourceExposure(ResourceScope.Machine)]
  526.         [ResourceConsumption(ResourceScope.Machine)]
  527.         public static byte[] ReadAllBytes(string path)
  528.         {
  529.             byte[] bytes;
  530.             using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) {
  531.                 // Do a blocking read
  532.                 int index = 0;
  533.                 long fileLength = fs.Length;
  534.                 if (fileLength > Int32.MaxValue)
  535.                     throw new IOException(Environment.GetResourceString("IO.IO_FileTooLong2GB"));
  536.                 int count = (int)fileLength;
  537.                 bytes = new byte[count];
  538.                 while (count > 0) {
  539.                     int n = fs.Read(bytes, index, count);
  540.                     if (n == 0)
  541.                         __Error.EndOfFile();
  542.                     index += n;
  543.                     count -= n;
  544.                 }
  545.             }
  546.             return bytes;
  547.         }
  548.        
  549.         [ResourceExposure(ResourceScope.Machine)]
  550.         [ResourceConsumption(ResourceScope.Machine)]
  551.         public static void WriteAllBytes(string path, byte[] bytes)
  552.         {
  553.             if (bytes == null)
  554.                 throw new ArgumentNullException("bytes");
  555.            
  556.             using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
  557.                 fs.Write(bytes, 0, bytes.Length);
  558.         }
  559.        
  560.         [ResourceExposure(ResourceScope.Machine)]
  561.         [ResourceConsumption(ResourceScope.Machine)]
  562.         public static string[] ReadAllLines(string path)
  563.         {
  564.             return ReadAllLines(path, Encoding.UTF8);
  565.         }
  566.        
  567.         [ResourceExposure(ResourceScope.Machine)]
  568.         [ResourceConsumption(ResourceScope.Machine)]
  569.         public static string[] ReadAllLines(string path, Encoding encoding)
  570.         {
  571.             string line;
  572.             ArrayList lines = new ArrayList();
  573.            
  574.             using (StreamReader sr = new StreamReader(path, encoding))
  575.                 while ((line = sr.ReadLine()) != null)
  576.                     lines.Add(line);
  577.            
  578.             return (string[])lines.ToArray(typeof(string));
  579.         }
  580.        
  581.         [ResourceExposure(ResourceScope.Machine)]
  582.         [ResourceConsumption(ResourceScope.Machine)]
  583.         public static void WriteAllLines(string path, string[] contents)
  584.         {
  585.             WriteAllLines(path, contents, StreamWriter.UTF8NoBOM);
  586.         }
  587.        
  588.         [ResourceExposure(ResourceScope.Machine)]
  589.         [ResourceConsumption(ResourceScope.Machine)]
  590.         public static void WriteAllLines(string path, string[] contents, Encoding encoding)
  591.         {
  592.             if (contents == null)
  593.                 throw new ArgumentNullException("contents");
  594.            
  595.             using (StreamWriter sw = new StreamWriter(path, false, encoding))
  596.                 foreach (string line in contents)
  597.                     sw.WriteLine(line);
  598.         }
  599.        
  600.         [ResourceExposure(ResourceScope.Machine)]
  601.         [ResourceConsumption(ResourceScope.Machine)]
  602.         public static void AppendAllText(string path, string contents)
  603.         {
  604.             AppendAllText(path, contents, StreamWriter.UTF8NoBOM);
  605.         }
  606.        
  607.         [ResourceExposure(ResourceScope.Machine)]
  608.         [ResourceConsumption(ResourceScope.Machine)]
  609.         public static void AppendAllText(string path, string contents, Encoding encoding)
  610.         {
  611.             using (StreamWriter sw = new StreamWriter(path, true, encoding))
  612.                 sw.Write(contents);
  613.         }
  614.        
  615.         // Moves a specified file to a new location and potentially a new file name.
  616.         // This method does work across volumes.
  617.         //
  618.         // The caller must have certain FileIOPermissions. The caller must
  619.         // have Read and Write permission to
  620.         // sourceFileName and Write
  621.         // permissions to destFileName.
  622.         //
  623.         [ResourceExposure(ResourceScope.Machine)]
  624.         [ResourceConsumption(ResourceScope.Machine)]
  625.         public static void Move(string sourceFileName, string destFileName)
  626.         {
  627.             if (sourceFileName == null || destFileName == null)
  628.                 throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), Environment.GetResourceString("ArgumentNull_FileName"));
  629.             if (sourceFileName.Length == 0 || destFileName.Length == 0)
  630.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName"));
  631.            
  632.             string fullSourceFileName = Path.GetFullPathInternal(sourceFileName);
  633.             new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new string[] {fullSourceFileName}, false, false).Demand();
  634.             string fullDestFileName = Path.GetFullPathInternal(destFileName);
  635.             new FileIOPermission(FileIOPermissionAccess.Write, new string[] {fullDestFileName}, false, false).Demand();
  636.            
  637.             if (!InternalExists(fullSourceFileName))
  638.                 __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName);
  639.            
  640.             if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName)) {
  641.                 __Error.WinIOError();
  642.             }
  643.         }
  644.        
  645.         [ResourceExposure(ResourceScope.Machine)]
  646.         [ResourceConsumption(ResourceScope.Machine)]
  647.         public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName)
  648.         {
  649.             Replace(sourceFileName, destinationFileName, destinationBackupFileName, false);
  650.         }
  651.        
  652.         [ResourceExposure(ResourceScope.Machine)]
  653.         [ResourceConsumption(ResourceScope.Machine)]
  654.         public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors)
  655.         {
  656.             if (sourceFileName == null)
  657.                 throw new ArgumentNullException("sourceFileName");
  658.             if (destinationFileName == null)
  659.                 throw new ArgumentNullException("destinationFileName");
  660.            
  661.             // Write permission to all three files, read permission to source
  662.             // and dest.
  663.             string fullSrcPath = Path.GetFullPathInternal(sourceFileName);
  664.             string fullDestPath = Path.GetFullPathInternal(destinationFileName);
  665.             string fullBackupPath = null;
  666.             if (destinationBackupFileName != null)
  667.                 fullBackupPath = Path.GetFullPathInternal(destinationBackupFileName);
  668.             FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, new string[] {fullSrcPath, fullDestPath});
  669.             if (destinationBackupFileName != null)
  670.                 perm.AddPathList(FileIOPermissionAccess.Write, fullBackupPath);
  671.             perm.Demand();
  672.            
  673.            
  674.             int flags = Win32Native.REPLACEFILE_WRITE_THROUGH;
  675.             if (ignoreMetadataErrors)
  676.                 flags |= Win32Native.REPLACEFILE_IGNORE_MERGE_ERRORS;
  677.            
  678.             bool r = Win32Native.ReplaceFile(fullDestPath, fullSrcPath, fullBackupPath, flags, IntPtr.Zero, IntPtr.Zero);
  679.             if (!r)
  680.                 __Error.WinIOError();
  681.         }
  682.        
  683.        
  684.         // Returns 0 on success, otherwise a Win32 error code. Note that
  685.         // classes should use -1 as the uninitialized state for dataInitialized.
  686.         [ResourceExposure(ResourceScope.Machine)]
  687.         [ResourceConsumption(ResourceScope.Machine)]
  688.         static internal int FillAttributeInfo(string path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
  689.         {
  690.             int dataInitialised = 0;
  691.             // someone has a handle to the file open, or other error
  692.             if (tryagain) {
  693.                 Win32Native.WIN32_FIND_DATA win95data;
  694.                 // We do this only on Win95 machines
  695.                 win95data = new Win32Native.WIN32_FIND_DATA();
  696.                
  697.                 // Remove trialing slash since this can cause grief to FindFirstFile. You will get an invalid argument error
  698.                 string tempPath = path.TrimEnd(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar});
  699.                
  700.                 // For floppy drives, normally the OS will pop up a dialog saying
  701.                 // there is no disk in drive A:, please insert one. We don't want that.
  702.                 // SetErrorMode will let us disable this, but we should set the error
  703.                 // mode back, since this may have wide-ranging effects.
  704.                 int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
  705.                 try {
  706.                     bool error = false;
  707.                     SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, win95data);
  708.                     try {
  709.                         if (handle.IsInvalid) {
  710.                             error = true;
  711.                             dataInitialised = Marshal.GetLastWin32Error();
  712.                            
  713.                             // floppy device not ready
  714.                             if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND || dataInitialised == Win32Native.ERROR_PATH_NOT_FOUND || dataInitialised == Win32Native.ERROR_NOT_READY) {
  715.                                 if (!returnErrorOnNotFound) {
  716.                                     // Return default value for backward compbatibility
  717.                                     dataInitialised = 0;
  718.                                     data.fileAttributes = -1;
  719.                                 }
  720.                             }
  721.                             return dataInitialised;
  722.                         }
  723.                     }
  724.                     finally {
  725.                         // Close the Win32 handle
  726.                         try {
  727.                             handle.Close();
  728.                         }
  729.                         catch {
  730.                             // if we're already returning an error, don't throw another one.
  731.                             if (!error) {
  732.                                 BCLDebug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
  733.                                 __Error.WinIOError();
  734.                             }
  735.                         }
  736.                     }
  737.                 }
  738.                 finally {
  739.                     Win32Native.SetErrorMode(oldMode);
  740.                 }
  741.                
  742.                 // Copy the information to data
  743.                 data.fileAttributes = win95data.dwFileAttributes;
  744.                 data.ftCreationTimeLow = (uint)win95data.ftCreationTime_dwLowDateTime;
  745.                 data.ftCreationTimeHigh = (uint)win95data.ftCreationTime_dwHighDateTime;
  746.                 data.ftLastAccessTimeLow = (uint)win95data.ftLastAccessTime_dwLowDateTime;
  747.                 data.ftLastAccessTimeHigh = (uint)win95data.ftLastAccessTime_dwHighDateTime;
  748.                 data.ftLastWriteTimeLow = (uint)win95data.ftLastWriteTime_dwLowDateTime;
  749.                 data.ftLastWriteTimeHigh = (uint)win95data.ftLastWriteTime_dwHighDateTime;
  750.                 data.fileSizeHigh = win95data.nFileSizeHigh;
  751.                 data.fileSizeLow = win95data.nFileSizeLow;
  752.             }
  753.             else {
  754.                
  755.                 // For floppy drives, normally the OS will pop up a dialog saying
  756.                 // there is no disk in drive A:, please insert one. We don't want that.
  757.                 // SetErrorMode will let us disable this, but we should set the error
  758.                 // mode back, since this may have wide-ranging effects.
  759.                 bool success = false;
  760.                 int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
  761.                 try {
  762.                     success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
  763.                 }
  764.                 finally {
  765.                     Win32Native.SetErrorMode(oldMode);
  766.                 }
  767.                
  768.                 if (!success) {
  769.                     dataInitialised = Marshal.GetLastWin32Error();
  770.                     // floppy device not ready
  771.                     if (dataInitialised != Win32Native.ERROR_FILE_NOT_FOUND && dataInitialised != Win32Native.ERROR_PATH_NOT_FOUND && dataInitialised != Win32Native.ERROR_NOT_READY) {
  772.                         // In case someone latched onto the file. Take the perf hit only for failure
  773.                         return FillAttributeInfo(path, ref data, true, returnErrorOnNotFound);
  774.                     }
  775.                     else {
  776.                         if (!returnErrorOnNotFound) {
  777.                             // Return default value for backward compbatibility
  778.                             dataInitialised = 0;
  779.                             data.fileAttributes = -1;
  780.                         }
  781.                     }
  782.                 }
  783.             }
  784.            
  785.             return dataInitialised;
  786.         }
  787.        
  788.         [ResourceExposure(ResourceScope.Machine)]
  789.         [ResourceConsumption(ResourceScope.Machine)]
  790.         private static FileStream OpenFile(string path, FileAccess access, out SafeFileHandle handle)
  791.         {
  792.             FileStream fs = new FileStream(path, FileMode.Open, access, FileShare.ReadWrite, 1);
  793.             handle = fs.SafeFileHandle;
  794.            
  795.             if (handle.IsInvalid) {
  796.                 // Return a meaningful error, using the RELATIVE path to
  797.                 // the file to avoid returning extra information to the caller.
  798.                
  799.                 // NT5 oddity - when trying to open "C:\" as a FileStream,
  800.                 // we usually get ERROR_PATH_NOT_FOUND from the OS. We should
  801.                 // probably be consistent w/ every other directory.
  802.                 int hr = Marshal.GetLastWin32Error();
  803.                 string FullPath = Path.GetFullPathInternal(path);
  804.                 if (hr == __Error.ERROR_PATH_NOT_FOUND && FullPath.Equals(Directory.GetDirectoryRoot(FullPath)))
  805.                     hr = __Error.ERROR_ACCESS_DENIED;
  806.                
  807.                
  808.                 __Error.WinIOError(hr, path);
  809.             }
  810.             return fs;
  811.         }
  812.        
  813.        
  814.         // Defined in WinError.h
  815.         private const int ERROR_INVALID_PARAMETER = 87;
  816.         private const int ERROR_ACCESS_DENIED = 5;
  817.     }
  818. }

Developer Fusion