<IoSources Include="$(BclSourcesRoot)\System\IO\BinaryReader.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\BinaryWriter.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\Directory.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\DirectoryInfo.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\SearchOption.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\DirectoryNotFoundException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\DriveNotFoundException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\EndOfStreamException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\File.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileAccess.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\FileInfo.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileLoadException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileMode.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileNotFoundException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileOptions.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileShare.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileSystemEnumerable.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\FileSystemInfo.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\FileAttributes.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\IOException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\MemoryStream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\PathTooLongException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\PinnedBufferMemoryStream.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\ReadLinesIterator.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\SeekOrigin.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\Stream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\StreamHelpers.CopyValidation.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\StreamReader.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\StreamWriter.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\TextReader.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\TextWriter.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryAccessor.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStreamWrapper.cs" />
{
[ComVisible(true)]
public static class Directory {
- public static DirectoryInfo GetParent(String path)
- {
- if (path==null)
- throw new ArgumentNullException(nameof(path));
-
- if (path.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), nameof(path));
- Contract.EndContractBlock();
-
- string fullPath = Path.GetFullPath(path);
-
- string s = Path.GetDirectoryName(fullPath);
- if (s==null)
- return null;
- return new DirectoryInfo(s);
- }
-
- public static DirectoryInfo CreateDirectory(String path) {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
-
- return InternalCreateDirectoryHelper(path);
- }
-
- internal static DirectoryInfo InternalCreateDirectoryHelper(String path)
- {
- Contract.Requires(path != null);
- Contract.Requires(path.Length != 0);
-
- String fullPath = Path.GetFullPath(path);
-
- InternalCreateDirectory(fullPath, path, null);
-
- return new DirectoryInfo(fullPath, false);
- }
-
- internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj)
- {
- int length = fullPath.Length;
-
- // We need to trim the trailing slash or the code will try to create 2 directories of the same name.
- if (length >= 2 && PathInternal.IsDirectorySeparator(fullPath[length - 1]))
- length--;
-
- int lengthRoot = PathInternal.GetRootLength(fullPath);
-
- // For UNC paths that are only // or ///
- if (length == 2 && PathInternal.IsDirectorySeparator(fullPath[1]))
- throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", path));
-
- // We can save a bunch of work if the directory we want to create already exists. This also
- // saves us in the case where sub paths are inaccessible (due to ERROR_ACCESS_DENIED) but the
- // final path is accessable and the directory already exists. For example, consider trying
- // to create c:\Foo\Bar\Baz, where everything already exists but ACLS prevent access to c:\Foo
- // and c:\Foo\Bar. In that case, this code will think it needs to create c:\Foo, and c:\Foo\Bar
- // and fail to due so, causing an exception to be thrown. This is not what we want.
- if (InternalExists(fullPath)) {
- return;
- }
-
- List<string> stackDir = new List<string>();
-
- // Attempt to figure out which directories don't exist, and only
- // create the ones we need. Note that InternalExists may fail due
- // to Win32 ACL's preventing us from seeing a directory, and this
- // isn't threadsafe.
-
- bool somepathexists = false;
-
- if (length > lengthRoot) { // Special case root (fullpath = X:\\)
- int i = length-1;
- while (i >= lengthRoot && !somepathexists) {
- String dir = fullPath.Substring(0, i+1);
-
- if (!InternalExists(dir)) // Create only the ones missing
- stackDir.Add(dir);
- else
- somepathexists = true;
-
- while (i > lengthRoot && fullPath[i] != Path.DirectorySeparatorChar && fullPath[i] != Path.AltDirectorySeparatorChar) i--;
- i--;
- }
- }
-
- int count = stackDir.Count;
-
- // If we were passed a DirectorySecurity, convert it to a security
- // descriptor and set it in he call to CreateDirectory.
- Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-
- bool r = true;
- int firstError = 0;
- String errorString = path;
- // If all the security checks succeeded create all the directories
- while (stackDir.Count > 0) {
- String name = stackDir[stackDir.Count - 1];
- stackDir.RemoveAt(stackDir.Count - 1);
- if (PathInternal.IsDirectoryTooLong(name))
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- r = Win32Native.CreateDirectory(name, secAttrs);
- if (!r && (firstError == 0)) {
- int currentError = Marshal.GetLastWin32Error();
- // While we tried to avoid creating directories that don't
- // exist above, there are at least two cases that will
- // cause us to see ERROR_ALREADY_EXISTS here. InternalExists
- // can fail because we didn't have permission to the
- // directory. Secondly, another thread or process could
- // create the directory between the time we check and the
- // time we try using the directory. Thirdly, it could
- // fail because the target does exist, but is a file.
- if (currentError != Win32Native.ERROR_ALREADY_EXISTS)
- firstError = currentError;
- else {
- // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw.
- if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED))
- {
- firstError = currentError;
- errorString = name;
- }
- }
- }
- }
-
- // We need this check to mask OS differences
- // Handle CreateDirectory("X:\\foo") when X: doesn't exist. Similarly for n/w paths.
- if ((count == 0) && !somepathexists) {
- String root = InternalGetDirectoryRoot(fullPath);
- if (!InternalExists(root)) {
- // Extract the root from the passed in path again for security.
- __Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, InternalGetDirectoryRoot(path));
- }
- return;
- }
-
- // Only throw an exception if creating the exact directory we
- // wanted failed to work correctly.
- if (!r && (firstError != 0)) {
- __Error.WinIOError(firstError, errorString);
- }
- }
-
-
- // Tests if the given path refers to an existing DirectoryInfo on disk.
- //
- // Your application must have Read permission to the directory's
- // contents.
- //
- public static bool Exists(String path)
- {
- return InternalExistsHelper(path);
- }
-
- internal static bool InternalExistsHelper(String path) {
- try
- {
- if (path == null)
- return false;
- if (path.Length == 0)
- return false;
-
- return InternalExists(Path.GetFullPath(path));
- }
- catch (ArgumentException) { }
- catch (NotSupportedException) { } // Security can throw this on ":"
- catch (SecurityException) { }
- catch (IOException) { }
- catch (UnauthorizedAccessException)
- {
- Debug.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only.");
- }
- return false;
- }
-
- // Determine whether path describes an existing directory
- // on disk, avoiding security checks.
- internal static bool InternalExists(String path) {
- int lastError = Win32Native.ERROR_SUCCESS;
- return InternalExists(path, out lastError);
- }
-
- // Determine whether path describes an existing directory
- // on disk, avoiding security checks.
- internal static bool InternalExists(String path, out int lastError) {
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- lastError = File.FillAttributeInfo(path, ref data, false, true);
-
- return (lastError == 0) && (data.fileAttributes != -1)
- && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0);
- }
-
- public static DateTime GetCreationTime(String path)
- {
- return File.GetCreationTime(path);
- }
-
- public static DateTime GetCreationTimeUtc(String path)
- {
- return File.GetCreationTimeUtc(path);
- }
-
- public static DateTime GetLastWriteTime(String path)
- {
- return File.GetLastWriteTime(path);
- }
-
- public static DateTime GetLastWriteTimeUtc(String path)
- {
- return File.GetLastWriteTimeUtc(path);
- }
-
- public static DateTime GetLastAccessTime(String path)
- {
- return File.GetLastAccessTime(path);
- }
-
- public static DateTime GetLastAccessTimeUtc(String path)
- {
- return File.GetLastAccessTimeUtc(path);
- }
-
- // Returns an array of filenames in the DirectoryInfo specified by path
- public static String[] GetFiles(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetFiles(path, "*", SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Files in the current DirectoryInfo matching the
- // given search pattern (ie, "*.txt").
- public static String[] GetFiles(String path, String searchPattern)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetFiles(path, searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Files in the current DirectoryInfo matching the
- // given search pattern (ie, "*.txt") and search option
- public static String[] GetFiles(String path, String searchPattern, SearchOption searchOption)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetFiles(path, searchPattern, searchOption);
- }
-
- // Returns an array of Files in the current DirectoryInfo matching the
- // given search pattern (ie, "*.txt") and search option
- private static String[] InternalGetFiles(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return InternalGetFileDirectoryNames(path, path, searchPattern, true, false, searchOption, true);
- }
-
- internal static String[] UnsafeGetFiles(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return InternalGetFileDirectoryNames(path, path, searchPattern, true, false, searchOption, false);
- }
-
- // Returns an array of Directories in the current directory.
- public static String[] GetDirectories(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetDirectories(path, "*", SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Directories in the current DirectoryInfo matching the
- // given search criteria (ie, "*.txt").
- public static String[] GetDirectories(String path, String searchPattern)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Directories in the current DirectoryInfo matching the
- // given search criteria (ie, "*.txt").
- public static String[] GetDirectories(String path, String searchPattern, SearchOption searchOption)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetDirectories(path, searchPattern, searchOption);
- }
-
- // Returns an array of Directories in the current DirectoryInfo matching the
- // given search criteria (ie, "*.txt").
- private static String[] InternalGetDirectories(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
- Contract.Ensures(Contract.Result<String[]>() != null);
-
- return InternalGetFileDirectoryNames(path, path, searchPattern, false, true, searchOption, true);
- }
-
- internal static String[] UnsafeGetDirectories(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
- Contract.Ensures(Contract.Result<String[]>() != null);
-
- return InternalGetFileDirectoryNames(path, path, searchPattern, false, true, searchOption, false);
- }
-
- // Returns an array of strongly typed FileSystemInfo entries in the path
- public static String[] GetFileSystemEntries(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of strongly typed FileSystemInfo entries in the path with the
- // given search criteria (ie, "*.txt"). We disallow .. as a part of the search criteria
- public static String[] GetFileSystemEntries(String path, String searchPattern)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetFileSystemEntries(path, searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of strongly typed FileSystemInfo entries in the path with the
- // given search criteria (ie, "*.txt"). We disallow .. as a part of the search criteria
- public static String[] GetFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.Ensures(Contract.Result<String[]>() != null);
- Contract.EndContractBlock();
-
- return InternalGetFileSystemEntries(path, searchPattern, searchOption);
- }
-
- private static String[] InternalGetFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return InternalGetFileDirectoryNames(path, path, searchPattern, true, true, searchOption, true);
- }
// Private class that holds search data that is passed around
// in the heap based stack recursion
public readonly SearchOption searchOption;
}
-
- // Returns fully qualified user path of dirs/files that matches the search parameters.
- // For recursive search this method will search through all the sub dirs and execute
- // the given search criteria against every dir.
- // For all the dirs/files returned, it will then demand path discovery permission for
- // their parent folders (it will avoid duplicate permission checks)
- internal static String[] InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, bool includeFiles, bool includeDirs, SearchOption searchOption, bool checkHost)
- {
- Contract.Requires(path != null);
- Contract.Requires(userPathOriginal != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- IEnumerable<String> enble = FileSystemEnumerableFactory.CreateFileNameIterator(
- path, userPathOriginal, searchPattern,
- includeFiles, includeDirs, searchOption, checkHost);
- List<String> fileList = new List<String>(enble);
- return fileList.ToArray();
- }
-
- public static IEnumerable<String> EnumerateDirectories(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
-
- return InternalEnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly);
- }
-
- public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalEnumerateDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern, SearchOption searchOption)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalEnumerateDirectories(path, searchPattern, searchOption);
- }
-
- private static IEnumerable<String> InternalEnumerateDirectories(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return EnumerateFileSystemNames(path, searchPattern, searchOption, false, true);
- }
-
- public static IEnumerable<String> EnumerateFiles(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
- Contract.EndContractBlock();
-
- return InternalEnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
- }
-
- public static IEnumerable<String> EnumerateFiles(String path, String searchPattern)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
- Contract.EndContractBlock();
-
- return InternalEnumerateFiles(path, searchPattern, SearchOption.TopDirectoryOnly);
- }
-
public static IEnumerable<String> EnumerateFiles(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
return EnumerateFileSystemNames(path, searchPattern, searchOption, true, false);
}
- public static IEnumerable<String> EnumerateFileSystemEntries(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
- Contract.EndContractBlock();
-
- return InternalEnumerateFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly);
- }
-
- public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
- Contract.EndContractBlock();
-
- return InternalEnumerateFileSystemEntries(path, searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
- Contract.EndContractBlock();
-
- return InternalEnumerateFileSystemEntries(path, searchPattern, searchOption);
- }
-
- private static IEnumerable<String> InternalEnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
- Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
-
- return EnumerateFileSystemNames(path, searchPattern, searchOption, true, true);
- }
-
private static IEnumerable<String> EnumerateFileSystemNames(String path, String searchPattern, SearchOption searchOption,
bool includeFiles, bool includeDirs)
{
includeFiles, includeDirs, searchOption, true);
}
- // Retrieves the names of the logical drives on this machine in the
- // form "C:\".
- //
- // Your application must have System Info permission.
- //
- public static String[] GetLogicalDrives()
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
-
-#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
-#pragma warning restore 618
-
- int drives = Win32Native.GetLogicalDrives();
- if (drives==0)
- __Error.WinIOError();
- uint d = (uint)drives;
- int count = 0;
- while (d != 0) {
- if (((int)d & 1) != 0) count++;
- d >>= 1;
- }
- String[] result = new String[count];
- char[] root = new char[] {'A', ':', '\\'};
- d = (uint)drives;
- count = 0;
- while (d != 0) {
- if (((int)d & 1) != 0) {
- result[count++] = new String(root);
- }
- d >>= 1;
- root[0]++;
- }
- return result;
- }
-
- public static String GetDirectoryRoot(String path) {
- if (path==null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
-
- string fullPath = Path.GetFullPath(path);
- string root = fullPath.Substring(0, PathInternal.GetRootLength(fullPath));
-
- return root;
- }
-
internal static String InternalGetDirectoryRoot(String path) {
if (path == null) return null;
return path.Substring(0, PathInternal.GetRootLength(path));
__Error.WinIOError(errorCode, fulldestDirName);
}
}
-
- public static void Move(String sourceDirName,String destDirName)
- {
- if (sourceDirName==null)
- throw new ArgumentNullException(nameof(sourceDirName));
- if (sourceDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceDirName));
- if (destDirName==null)
- throw new ArgumentNullException(nameof(destDirName));
- if (destDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName));
-
- String sourcePath = Path.GetFullPath(sourceDirName);
- String destPath = Path.GetFullPath(destDirName);
-
- if (String.Compare(sourcePath, destPath, StringComparison.OrdinalIgnoreCase) == 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent"));
-
- String sourceRoot = Path.GetPathRoot(sourcePath);
- String destinationRoot = Path.GetPathRoot(destPath);
- if (String.Compare(sourceRoot, destinationRoot, StringComparison.OrdinalIgnoreCase) != 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustHaveSameRoot"));
-
- if (!Win32Native.MoveFile(sourceDirName, destDirName))
- {
- int hr = Marshal.GetLastWin32Error();
- if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found
- {
- hr = Win32Native.ERROR_PATH_NOT_FOUND;
- __Error.WinIOError(hr, sourcePath);
- }
- // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons.
- if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp.
- throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", sourceDirName), Win32Native.MakeHRFromErrorCode(hr));
- __Error.WinIOError(hr, String.Empty);
- }
- }
-
- public static void Delete(String path)
- {
- String fullPath = Path.GetFullPath(path);
- Delete(fullPath, path, false);
- }
-
- public static void Delete(String path, bool recursive)
- {
- String fullPath = Path.GetFullPath(path);
- Delete(fullPath, path, recursive);
- }
-
- // Called from DirectoryInfo as well. FullPath is fully qualified,
- // while the user path is used for feedback in exceptions.
- internal static void Delete(String fullPath, String userPath, bool recursive)
- {
- // Do not recursively delete through reparse points. Perhaps in a
- // future version we will add a new flag to control this behavior,
- // but for now we're much safer if we err on the conservative side.
- // This applies to symbolic links and mount points.
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- int dataInitialised = File.FillAttributeInfo(fullPath, ref data, false, true);
- if (dataInitialised != 0) {
- // Ensure we throw a DirectoryNotFoundException.
- if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND)
- dataInitialised = Win32Native.ERROR_PATH_NOT_FOUND;
- __Error.WinIOError(dataInitialised, fullPath);
- }
-
- if (((FileAttributes)data.fileAttributes & FileAttributes.ReparsePoint) != 0)
- recursive = false;
-
- DeleteHelper(fullPath, userPath, recursive, true);
- }
-
- // Note that fullPath is fully qualified, while userPath may be relative.
- private static void DeleteHelper(String fullPath, String userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound)
- {
- bool r;
- int hr;
- Exception ex = null;
-
- // Do not recursively delete through reparse points. Perhaps in a
- // future version we will add a new flag to control this behavior,
- // but for now we're much safer if we err on the conservative side.
- // This applies to symbolic links and mount points.
- // Note the logic to check whether fullPath is a reparse point is
- // in Delete(String, String, bool), and will set "recursive" to false.
- // Note that Win32's DeleteFile and RemoveDirectory will just delete
- // the reparse point itself.
-
- if (recursive) {
- Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
-
- // Open a Find handle
- using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath + Path.DirectorySeparatorChar + "*", data)) {
- if (hnd.IsInvalid) {
- hr = Marshal.GetLastWin32Error();
- __Error.WinIOError(hr, fullPath);
- }
-
- do {
- bool isDir = (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
- if (isDir) {
- // Skip ".", "..".
- if (data.cFileName.Equals(".") || data.cFileName.Equals(".."))
- continue;
-
- // Recurse for all directories, unless they are
- // reparse points. Do not follow mount points nor
- // symbolic links, but do delete the reparse point
- // itself.
- bool shouldRecurse = (0 == (data.dwFileAttributes & (int) FileAttributes.ReparsePoint));
- if (shouldRecurse) {
- String newFullPath = Path.Combine(fullPath, data.cFileName);
- String newUserPath = Path.Combine(userPath, data.cFileName);
- try {
- DeleteHelper(newFullPath, newUserPath, recursive, false);
- }
- catch(Exception e) {
- if (ex == null) {
- ex = e;
- }
- }
- }
- else {
- // Check to see if this is a mount point, and
- // unmount it.
- if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT) {
- // Use full path plus a trailing '\'
- String mountPoint = Path.Combine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
- r = Win32Native.DeleteVolumeMountPoint(mountPoint);
- if (!r) {
- hr = Marshal.GetLastWin32Error();
- if (hr != Win32Native.ERROR_PATH_NOT_FOUND) {
- try {
- __Error.WinIOError(hr, data.cFileName);
- }
- catch(Exception e) {
- if (ex == null) {
- ex = e;
- }
- }
- }
- }
- }
-
- // RemoveDirectory on a symbolic link will
- // remove the link itself.
- String reparsePoint = Path.Combine(fullPath, data.cFileName);
- r = Win32Native.RemoveDirectory(reparsePoint);
- if (!r) {
- hr = Marshal.GetLastWin32Error();
- if (hr != Win32Native.ERROR_PATH_NOT_FOUND) {
- try {
- __Error.WinIOError(hr, data.cFileName);
- }
- catch(Exception e) {
- if (ex == null) {
- ex = e;
- }
- }
- }
- }
- }
- }
- else {
- String fileName = Path.Combine(fullPath, data.cFileName);
- r = Win32Native.DeleteFile(fileName);
- if (!r) {
- hr = Marshal.GetLastWin32Error();
- if (hr != Win32Native.ERROR_FILE_NOT_FOUND) {
- try {
- __Error.WinIOError(hr, data.cFileName);
- }
- catch (Exception e) {
- if (ex == null) {
- ex = e;
- }
- }
- }
- }
- }
- } while (Win32Native.FindNextFile(hnd, data));
- // Make sure we quit with a sensible error.
- hr = Marshal.GetLastWin32Error();
- }
-
- if (ex != null)
- throw ex;
- if (hr!=0 && hr!=Win32Native.ERROR_NO_MORE_FILES)
- __Error.WinIOError(hr, userPath);
- }
-
- r = Win32Native.RemoveDirectory(fullPath);
-
- if (!r) {
- hr = Marshal.GetLastWin32Error();
- if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code.
- hr = Win32Native.ERROR_PATH_NOT_FOUND;
- // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons.
- if (hr == Win32Native.ERROR_ACCESS_DENIED)
- throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", userPath));
-
- // don't throw the DirectoryNotFoundException since this is a subdir and there could be a race condition
- // between two Directory.Delete callers
- if (hr == Win32Native.ERROR_PATH_NOT_FOUND && !throwOnTopLevelDirectoryNotFound)
- return;
-
- __Error.WinIOError(hr, fullPath);
- }
- }
}
}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exposes routines for enumerating through a
-** directory.
-**
-** April 11,2000
-**
-===========================================================*/
-
-using System.Collections.Generic;
-using Microsoft.Win32;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Runtime.Versioning;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.IO
-{
- [Serializable]
- [ComVisible(true)]
- public sealed class DirectoryInfo : FileSystemInfo
- {
- // Migrating InheritanceDemands requires this default ctor, so we can annotate it.
- private DirectoryInfo(){}
-
- public DirectoryInfo(String path)
- {
- if (path==null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
-
- Init(path);
- }
-
- private void Init(String path)
- {
- // Special case "<DriveLetter>:" to point to "<CurrentDirectory>" instead
- if ((path.Length == 2) && (path[1] == ':'))
- {
- OriginalPath = ".";
- }
- else
- {
- OriginalPath = path;
- }
-
- FullPath = Path.GetFullPath(path); ;
- DisplayPath = GetDisplayName(OriginalPath, FullPath);
- }
-
- internal DirectoryInfo(String fullPath, bool junk)
- {
- Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
- // Fast path when we know a DirectoryInfo exists.
- OriginalPath = Path.GetFileName(fullPath);
-
- FullPath = fullPath;
- DisplayPath = GetDisplayName(OriginalPath, FullPath);
- }
-
- private DirectoryInfo(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- DisplayPath = GetDisplayName(OriginalPath, FullPath);
- }
-
- public override String Name
- {
- get
- {
- // DisplayPath is dir name for coreclr
- return DisplayPath;
- }
- }
-
- public DirectoryInfo Parent {
- get {
- String parentName;
- // FullPath might be either "c:\bar" or "c:\bar\". Handle
- // those cases, as well as avoiding mangling "c:\".
- String s = FullPath;
- if (s.Length > 3 && s.EndsWith(Path.DirectorySeparatorChar))
- s = FullPath.Substring(0, FullPath.Length - 1);
- parentName = Path.GetDirectoryName(s);
- if (parentName==null)
- return null;
-
- return new DirectoryInfo(parentName, false);
- }
- }
-
- public DirectoryInfo CreateSubdirectory(String path) {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
-
- return CreateSubdirectory(path, null);
- }
-
- public DirectoryInfo CreateSubdirectory(String path, Object directorySecurity)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
-
- return CreateSubdirectoryHelper(path, directorySecurity);
- }
-
- private DirectoryInfo CreateSubdirectoryHelper(String path, Object directorySecurity)
- {
- Contract.Requires(path != null);
-
- String newDirs = Path.Combine(FullPath, path);
- String fullPath = Path.GetFullPath(newDirs);
-
- if (0!=String.Compare(FullPath,0,fullPath,0, FullPath.Length,StringComparison.OrdinalIgnoreCase)) {
- String displayPath = __Error.GetDisplayablePath(DisplayPath, false);
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSubPath", path, displayPath));
- }
-
- Directory.InternalCreateDirectory(fullPath, path, directorySecurity);
-
- // Check for read permission to directory we hand back by calling this constructor.
- return new DirectoryInfo(fullPath);
- }
-
- public void Create()
- {
- Directory.InternalCreateDirectory(FullPath, OriginalPath, null);
- }
-
- // Tests if the given path refers to an existing DirectoryInfo on disk.
- public override bool Exists {
- get
- {
- try
- {
- if (_dataInitialised == -1)
- Refresh();
- if (_dataInitialised != 0) // Refresh was unable to initialise the data
- return false;
- return _data.fileAttributes != -1 && (_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0;
- }
- catch
- {
- return false;
- }
- }
- }
-
- // Returns an array of Files in the current DirectoryInfo matching the
- // given search criteria (ie, "*.txt").
- public FileInfo[] GetFiles(String searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalGetFiles(searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Files in the current DirectoryInfo matching the
- // given search criteria (ie, "*.txt").
- public FileInfo[] GetFiles(String searchPattern, SearchOption searchOption)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalGetFiles(searchPattern, searchOption);
- }
-
- // Returns an array of Files in the current DirectoryInfo matching the
- // given search criteria (ie, "*.txt").
- private FileInfo[] InternalGetFiles(String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- IEnumerable<FileInfo> enble = FileSystemEnumerableFactory.CreateFileInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
- List<FileInfo> fileList = new List<FileInfo>(enble);
- return fileList.ToArray();
- }
-
- // Returns an array of Files in the DirectoryInfo specified by path
- public FileInfo[] GetFiles()
- {
- return InternalGetFiles("*", SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Directories in the current directory.
- public DirectoryInfo[] GetDirectories()
- {
- return InternalGetDirectories("*", SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of strongly typed FileSystemInfo entries in the path with the
- // given search criteria (ie, "*.txt").
- public FileSystemInfo[] GetFileSystemInfos(String searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalGetFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of strongly typed FileSystemInfo entries in the path with the
- // given search criteria (ie, "*.txt").
- public FileSystemInfo[] GetFileSystemInfos(String searchPattern, SearchOption searchOption)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalGetFileSystemInfos(searchPattern, searchOption);
- }
-
- // Returns an array of strongly typed FileSystemInfo entries in the path with the
- // given search criteria (ie, "*.txt").
- private FileSystemInfo[] InternalGetFileSystemInfos(String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- IEnumerable<FileSystemInfo> enble = FileSystemEnumerableFactory.CreateFileSystemInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
- List<FileSystemInfo> fileList = new List<FileSystemInfo>(enble);
- return fileList.ToArray();
- }
-
- // Returns an array of strongly typed FileSystemInfo entries which will contain a listing
- // of all the files and directories.
- public FileSystemInfo[] GetFileSystemInfos()
- {
- return InternalGetFileSystemInfos("*", SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Directories in the current DirectoryInfo matching the
- // given search criteria (ie, "System*" could match the System & System32
- // directories).
- public DirectoryInfo[] GetDirectories(String searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalGetDirectories(searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- // Returns an array of Directories in the current DirectoryInfo matching the
- // given search criteria (ie, "System*" could match the System & System32
- // directories).
- public DirectoryInfo[] GetDirectories(String searchPattern, SearchOption searchOption)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalGetDirectories(searchPattern, searchOption);
- }
-
- // Returns an array of Directories in the current DirectoryInfo matching the
- // given search criteria (ie, "System*" could match the System & System32
- // directories).
- private DirectoryInfo[] InternalGetDirectories(String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- IEnumerable<DirectoryInfo> enble = FileSystemEnumerableFactory.CreateDirectoryInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
- List<DirectoryInfo> fileList = new List<DirectoryInfo>(enble);
- return fileList.ToArray();
- }
-
- public IEnumerable<DirectoryInfo> EnumerateDirectories()
- {
- return InternalEnumerateDirectories("*", SearchOption.TopDirectoryOnly);
- }
-
- public IEnumerable<DirectoryInfo> EnumerateDirectories(String searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalEnumerateDirectories(searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- public IEnumerable<DirectoryInfo> EnumerateDirectories(String searchPattern, SearchOption searchOption)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalEnumerateDirectories(searchPattern, searchOption);
- }
-
- private IEnumerable<DirectoryInfo> InternalEnumerateDirectories(String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return FileSystemEnumerableFactory.CreateDirectoryInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
- }
-
- public IEnumerable<FileInfo> EnumerateFiles()
- {
- return InternalEnumerateFiles("*", SearchOption.TopDirectoryOnly);
- }
-
- public IEnumerable<FileInfo> EnumerateFiles(String searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalEnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- public IEnumerable<FileInfo> EnumerateFiles(String searchPattern, SearchOption searchOption)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalEnumerateFiles(searchPattern, searchOption);
- }
-
- private IEnumerable<FileInfo> InternalEnumerateFiles(String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return FileSystemEnumerableFactory.CreateFileInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
- }
-
- public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos()
- {
- return InternalEnumerateFileSystemInfos("*", SearchOption.TopDirectoryOnly);
- }
-
- public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(String searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- Contract.EndContractBlock();
-
- return InternalEnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
- }
-
- public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(String searchPattern, SearchOption searchOption)
- {
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- Contract.EndContractBlock();
-
- return InternalEnumerateFileSystemInfos(searchPattern, searchOption);
- }
-
- private IEnumerable<FileSystemInfo> InternalEnumerateFileSystemInfos(String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(searchPattern != null);
- Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return FileSystemEnumerableFactory.CreateFileSystemInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
- }
-
- // Returns the root portion of the given path. The resulting string
- // consists of those rightmost characters of the path that constitute the
- // root of the path. Possible patterns for the resulting string are: An
- // empty string (a relative path on the current drive), "\" (an absolute
- // path on the current drive), "X:" (a relative path on a given drive,
- // where X is the drive letter), "X:\" (an absolute path on a given drive),
- // and "\\server\share" (a UNC path for a given server and share name).
- // The resulting string is null if path is null.
- public DirectoryInfo Root {
- get
- {
- int rootLength = PathInternal.GetRootLength(FullPath);
- String rootPath = FullPath.Substring(0, rootLength);
-
- return new DirectoryInfo(rootPath);
- }
- }
-
- public void MoveTo(String destDirName) {
- if (destDirName==null)
- throw new ArgumentNullException(nameof(destDirName));
- if (destDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName));
- Contract.EndContractBlock();
-
- String fullDestDirName = Path.GetFullPath(destDirName);
- if (!fullDestDirName.EndsWith(Path.DirectorySeparatorChar))
- fullDestDirName = fullDestDirName + Path.DirectorySeparatorChar;
-
- String fullSourcePath;
- if (FullPath.EndsWith(Path.DirectorySeparatorChar))
- fullSourcePath = FullPath;
- else
- fullSourcePath = FullPath + Path.DirectorySeparatorChar;
-
- if (String.Compare(fullSourcePath, fullDestDirName, StringComparison.OrdinalIgnoreCase) == 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent"));
-
- String sourceRoot = Path.GetPathRoot(fullSourcePath);
- String destinationRoot = Path.GetPathRoot(fullDestDirName);
-
- if (String.Compare(sourceRoot, destinationRoot, StringComparison.OrdinalIgnoreCase) != 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustHaveSameRoot"));
-
- if (!Win32Native.MoveFile(FullPath, destDirName))
- {
- int hr = Marshal.GetLastWin32Error();
- if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code
- {
- hr = Win32Native.ERROR_PATH_NOT_FOUND;
- __Error.WinIOError(hr, DisplayPath);
- }
-
- if (hr == Win32Native.ERROR_ACCESS_DENIED) // We did this for Win9x. We can't change it for backcomp.
- throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", DisplayPath));
-
- __Error.WinIOError(hr,String.Empty);
- }
- FullPath = fullDestDirName;
- OriginalPath = destDirName;
- DisplayPath = GetDisplayName(OriginalPath, FullPath);
-
- // Flush any cached information about the directory.
- _dataInitialised = -1;
- }
-
- public override void Delete()
- {
- Directory.Delete(FullPath, OriginalPath, false);
- }
-
- public void Delete(bool recursive)
- {
- Directory.Delete(FullPath, OriginalPath, recursive);
- }
-
- // Returns the fully qualified path
- public override String ToString()
- {
- return DisplayPath;
- }
-
- private static String GetDisplayName(String originalPath, String fullPath)
- {
- Debug.Assert(originalPath != null);
- Debug.Assert(fullPath != null);
-
- String displayName = "";
-
- // Special case "<DriveLetter>:" to point to "<CurrentDirectory>" instead
- if ((originalPath.Length == 2) && (originalPath[1] == ':'))
- {
- displayName = ".";
- }
- else
- {
- displayName = GetDirName(fullPath);
- }
- return displayName;
- }
-
- private static String GetDirName(String fullPath)
- {
- Debug.Assert(fullPath != null);
-
- String dirName = null;
- if (fullPath.Length > 3)
- {
- String s = fullPath;
- if (fullPath.EndsWith(Path.DirectorySeparatorChar))
- {
- s = fullPath.Substring(0, fullPath.Length - 1);
- }
- dirName = Path.GetFileName(s);
- }
- else
- {
- dirName = fullPath; // For rooted paths, like "c:\"
- }
- return dirName;
- }
- }
-}
-
private const int GetFileExInfoStandard = 0;
- public static StreamReader OpenText(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
- return new StreamReader(path);
- }
-
- public static StreamWriter CreateText(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
- return new StreamWriter(path,false);
- }
-
- public static StreamWriter AppendText(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
- return new StreamWriter(path,true);
- }
-
-
- // Copies an existing file to a new file. An exception is raised if the
- // destination file already exists. Use the
- // Copy(String, String, boolean) method to allow
- // overwriting an existing file.
- public static void Copy(String sourceFileName, String destFileName) {
- if (sourceFileName == null)
- throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (destFileName == null)
- throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName));
- if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
- Contract.EndContractBlock();
-
- InternalCopy(sourceFileName, destFileName, false);
- }
-
- // Copies an existing file to a new file. If overwrite is
- // false, then an IOException is thrown if the destination file
- // already exists. If overwrite is true, the file is
- // overwritten.
- public static void Copy(String sourceFileName, String destFileName, bool overwrite) {
- if (sourceFileName == null)
- throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (destFileName == null)
- throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName));
- if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
- Contract.EndContractBlock();
-
- InternalCopy(sourceFileName, destFileName, overwrite);
- }
-
- /// <devdoc>
- /// Note: This returns the fully qualified name of the destination file.
- /// </devdoc>
- internal static String InternalCopy(String sourceFileName, String destFileName, bool overwrite)
- {
- Contract.Requires(sourceFileName != null);
- Contract.Requires(destFileName != null);
- Contract.Requires(sourceFileName.Length > 0);
- Contract.Requires(destFileName.Length > 0);
-
- String fullSourceFileName = Path.GetFullPath(sourceFileName);
- String fullDestFileName = Path.GetFullPath(destFileName);
-
- bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite);
- if (!r) {
- // Save Win32 error because subsequent checks will overwrite this HRESULT.
- int errorCode = Marshal.GetLastWin32Error();
- String fileName = destFileName;
-
- if (errorCode != Win32Native.ERROR_FILE_EXISTS) {
- if (errorCode == Win32Native.ERROR_ACCESS_DENIED) {
- if (Directory.InternalExists(fullDestFileName))
- throw new IOException(Environment.GetResourceString("Arg_FileIsDirectory_Name", destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName);
- }
- }
-
- __Error.WinIOError(errorCode, fileName);
- }
-
- return fullDestFileName;
- }
-
- // Creates a file in a particular path. If the file exists, it is replaced.
- // The file is opened with ReadWrite accessand cannot be opened by another
- // application until it has been closed. An IOException is thrown if the
- // directory specified doesn't exist.
- public static FileStream Create(String path) {
- return Create(path, FileStream.DefaultBufferSize);
- }
-
- // Creates a file in a particular path. If the file exists, it is replaced.
- // The file is opened with ReadWrite access and cannot be opened by another
- // application until it has been closed. An IOException is thrown if the
- // directory specified doesn't exist.
- public static FileStream Create(String path, int bufferSize) {
- return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize);
- }
-
- public static FileStream Create(String path, int bufferSize, FileOptions options) {
- return new FileStream(path, FileMode.Create, FileAccess.ReadWrite,
- FileShare.None, bufferSize, options);
- }
-
- // Deletes a file. The file specified by the designated path is deleted.
- // If the file does not exist, Delete succeeds without throwing
- // an exception.
- //
- // On NT, Delete will fail for a file that is open for normal I/O
- // or a file that is memory mapped.
- public static void Delete(String path) {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- Contract.EndContractBlock();
-
- InternalDelete(path);
- }
-
- internal static void InternalDelete(String path)
- {
- String fullPath = Path.GetFullPath(path);
- bool r = Win32Native.DeleteFile(fullPath);
- if (!r) {
- int hr = Marshal.GetLastWin32Error();
- if (hr==Win32Native.ERROR_FILE_NOT_FOUND)
- return;
- else
- __Error.WinIOError(hr, fullPath);
- }
- }
-
// Tests if a file exists. The result is true if the file
// given by the specified path exists; otherwise, the result is
// false. Note that if path describes a directory,
&& ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0);
}
- public static FileStream Open(String path, FileMode mode) {
- return Open(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.None);
- }
-
- public static FileStream Open(String path, FileMode mode, FileAccess access) {
- return Open(path,mode, access, FileShare.None);
- }
-
- public static FileStream Open(String path, FileMode mode, FileAccess access, FileShare share) {
- return new FileStream(path, mode, access, share);
- }
-
- public static DateTime GetCreationTime(String path)
- {
- return InternalGetCreationTimeUtc(path).ToLocalTime();
- }
-
- public static DateTime GetCreationTimeUtc(String path)
- {
- return InternalGetCreationTimeUtc(path); // this API isn't exposed in Silverlight
- }
-
- private static DateTime InternalGetCreationTimeUtc(String path)
- {
- String fullPath = Path.GetFullPath(path);
-
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
- if (dataInitialised != 0)
- __Error.WinIOError(dataInitialised, fullPath);
-
- long dt = ((long)(data.ftCreationTimeHigh) << 32) | ((long)data.ftCreationTimeLow);
- return DateTime.FromFileTimeUtc(dt);
- }
-
- public static DateTime GetLastAccessTime(String path)
- {
- return InternalGetLastAccessTimeUtc(path).ToLocalTime();
- }
-
- public static DateTime GetLastAccessTimeUtc(String path)
- {
- return InternalGetLastAccessTimeUtc(path);
- }
-
- private static DateTime InternalGetLastAccessTimeUtc(String path)
- {
- String fullPath = Path.GetFullPath(path);
-
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
- if (dataInitialised != 0)
- __Error.WinIOError(dataInitialised, fullPath);
-
- long dt = ((long)(data.ftLastAccessTimeHigh) << 32) | ((long)data.ftLastAccessTimeLow);
- return DateTime.FromFileTimeUtc(dt);
- }
-
- public static DateTime GetLastWriteTime(String path)
- {
- return InternalGetLastWriteTimeUtc(path).ToLocalTime();
- }
-
- public static DateTime GetLastWriteTimeUtc(String path)
- {
- return InternalGetLastWriteTimeUtc(path);
- }
-
- private static DateTime InternalGetLastWriteTimeUtc(String path)
- {
- String fullPath = Path.GetFullPath(path);
-
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
- if (dataInitialised != 0)
- __Error.WinIOError(dataInitialised, fullPath);
-
- long dt = ((long)data.ftLastWriteTimeHigh << 32) | ((long)data.ftLastWriteTimeLow);
- return DateTime.FromFileTimeUtc(dt);
- }
-
- public static FileAttributes GetAttributes(String path)
- {
- String fullPath = Path.GetFullPath(path);
-
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- int dataInitialised = FillAttributeInfo(fullPath, ref data, false, true);
- if (dataInitialised != 0)
- __Error.WinIOError(dataInitialised, fullPath);
-
- return (FileAttributes) data.fileAttributes;
- }
-
- public static void SetAttributes(String path, FileAttributes fileAttributes)
- {
- String fullPath = Path.GetFullPath(path);
- bool r = Win32Native.SetFileAttributes(fullPath, (int) fileAttributes);
- if (!r) {
- int hr = Marshal.GetLastWin32Error();
- if (hr==ERROR_INVALID_PARAMETER)
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs"));
- __Error.WinIOError(hr, fullPath);
- }
- }
-
- public static FileStream OpenRead(String path) {
- return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
- }
-
- public static FileStream OpenWrite(String path) {
- return new FileStream(path, FileMode.OpenOrCreate,
- FileAccess.Write, FileShare.None);
- }
-
- public static String ReadAllText(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- return InternalReadAllText(path, Encoding.UTF8);
- }
-
- public static String ReadAllText(String path, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- return InternalReadAllText(path, encoding);
- }
-
- private static String InternalReadAllText(String path, Encoding encoding)
- {
- Contract.Requires(path != null);
- Contract.Requires(encoding != null);
- Contract.Requires(path.Length > 0);
-
- using (StreamReader sr = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize))
- return sr.ReadToEnd();
- }
-
- public static void WriteAllText(String path, String contents)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM);
- }
-
- public static void WriteAllText(String path, String contents, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllText(path, contents, encoding);
- }
-
- private static void InternalWriteAllText(String path, String contents, Encoding encoding)
- {
- Contract.Requires(path != null);
- Contract.Requires(encoding != null);
- Contract.Requires(path.Length > 0);
-
- using (StreamWriter sw = new StreamWriter(path, false, encoding, StreamWriter.DefaultBufferSize))
- sw.Write(contents);
- }
-
public static byte[] ReadAllBytes(String path)
{
byte[] bytes;
return bytes;
}
- public static void WriteAllBytes(String path, byte[] bytes)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path), Environment.GetResourceString("ArgumentNull_Path"));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- if (bytes == null)
- throw new ArgumentNullException(nameof(bytes));
- Contract.EndContractBlock();
-
- InternalWriteAllBytes(path, bytes);
- }
-
- private static void InternalWriteAllBytes(String path, byte[] bytes)
- {
- Contract.Requires(path != null);
- Contract.Requires(path.Length != 0);
- Contract.Requires(bytes != null);
-
- using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read,
- FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false))
- {
- fs.Write(bytes, 0, bytes.Length);
- }
- }
-
public static String[] ReadAllLines(String path)
{
if (path == null)
return InternalReadAllLines(path, Encoding.UTF8);
}
- public static String[] ReadAllLines(String path, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- return InternalReadAllLines(path, encoding);
- }
-
private static String[] InternalReadAllLines(String path, Encoding encoding)
{
Contract.Requires(path != null);
return lines.ToArray();
}
-
- public static IEnumerable<String> ReadLines(String path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(path));
- Contract.EndContractBlock();
-
- return ReadLinesIterator.CreateIterator(path, Encoding.UTF8);
- }
-
- public static IEnumerable<String> ReadLines(String path, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(path));
- Contract.EndContractBlock();
-
- return ReadLinesIterator.CreateIterator(path, encoding);
- }
-
- public static void WriteAllLines(String path, String[] contents)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (contents == null)
- throw new ArgumentNullException(nameof(contents));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllLines(new StreamWriter(path, false, StreamWriter.UTF8NoBOM), contents);
- }
-
- public static void WriteAllLines(String path, String[] contents, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (contents == null)
- throw new ArgumentNullException(nameof(contents));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllLines(new StreamWriter(path, false, encoding), contents);
- }
-
- public static void WriteAllLines(String path, IEnumerable<String> contents)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (contents == null)
- throw new ArgumentNullException(nameof(contents));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllLines(new StreamWriter(path, false, StreamWriter.UTF8NoBOM), contents);
- }
-
- public static void WriteAllLines(String path, IEnumerable<String> contents, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (contents == null)
- throw new ArgumentNullException(nameof(contents));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllLines(new StreamWriter(path, false, encoding), contents);
- }
-
- private static void InternalWriteAllLines(TextWriter writer, IEnumerable<String> contents)
- {
- Contract.Requires(writer != null);
- Contract.Requires(contents != null);
-
- using (writer)
- {
- foreach (String line in contents)
- {
- writer.WriteLine(line);
- }
- }
- }
-
- public static void AppendAllText(String path, String contents)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalAppendAllText(path, contents, StreamWriter.UTF8NoBOM);
- }
-
- public static void AppendAllText(String path, String contents, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalAppendAllText(path, contents, encoding);
- }
-
- private static void InternalAppendAllText(String path, String contents, Encoding encoding)
- {
- Contract.Requires(path != null);
- Contract.Requires(encoding != null);
- Contract.Requires(path.Length > 0);
-
- using (StreamWriter sw = new StreamWriter(path, true, encoding))
- sw.Write(contents);
- }
-
- public static void AppendAllLines(String path, IEnumerable<String> contents)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (contents == null)
- throw new ArgumentNullException(nameof(contents));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllLines(new StreamWriter(path, true, StreamWriter.UTF8NoBOM), contents);
- }
-
- public static void AppendAllLines(String path, IEnumerable<String> contents, Encoding encoding)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (contents == null)
- throw new ArgumentNullException(nameof(contents));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- InternalWriteAllLines(new StreamWriter(path, true, encoding), contents);
- }
-
- // Moves a specified file to a new location and potentially a new file name.
- // This method does work across volumes.
- public static void Move(String sourceFileName, String destFileName) {
- InternalMove(sourceFileName, destFileName);
- }
-
- private static void InternalMove(String sourceFileName, String destFileName) {
- if (sourceFileName == null)
- throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (destFileName == null)
- throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName));
- if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
- Contract.EndContractBlock();
-
- String fullSourceFileName = Path.GetFullPath(sourceFileName);
- String fullDestFileName = Path.GetFullPath(destFileName);
-
- if (!InternalExists(fullSourceFileName))
- __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName);
-
- if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName))
- {
- __Error.WinIOError();
- }
- }
-
-
- public static void Replace(String sourceFileName, String destinationFileName, String destinationBackupFileName)
- {
- if (sourceFileName == null)
- throw new ArgumentNullException(nameof(sourceFileName));
- if (destinationFileName == null)
- throw new ArgumentNullException(nameof(destinationFileName));
- Contract.EndContractBlock();
-
- InternalReplace(sourceFileName, destinationFileName, destinationBackupFileName, false);
- }
-
- public static void Replace(String sourceFileName, String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors)
- {
- if (sourceFileName == null)
- throw new ArgumentNullException(nameof(sourceFileName));
- if (destinationFileName == null)
- throw new ArgumentNullException(nameof(destinationFileName));
- Contract.EndContractBlock();
-
- InternalReplace(sourceFileName, destinationFileName, destinationBackupFileName, ignoreMetadataErrors);
- }
-
- private static void InternalReplace(String sourceFileName, String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors)
- {
- Contract.Requires(sourceFileName != null);
- Contract.Requires(destinationFileName != null);
-
- String fullSrcPath = Path.GetFullPath(sourceFileName);
- String fullDestPath = Path.GetFullPath(destinationFileName);
- String fullBackupPath = null;
- if (destinationBackupFileName != null)
- fullBackupPath = Path.GetFullPath(destinationBackupFileName);
-
- int flags = Win32Native.REPLACEFILE_WRITE_THROUGH;
- if (ignoreMetadataErrors)
- flags |= Win32Native.REPLACEFILE_IGNORE_MERGE_ERRORS;
-
- bool r = Win32Native.ReplaceFile(fullDestPath, fullSrcPath, fullBackupPath, flags, IntPtr.Zero, IntPtr.Zero);
- if (!r)
- __Error.WinIOError();
- }
-
-
+
// Returns 0 on success, otherwise a Win32 error code. Note that
// classes should use -1 as the uninitialized state for dataInitialized.
internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-** Purpose: File attribute flags corresponding to NT's flags.
-**
-**
-===========================================================*/
-using System;
-
-namespace System.IO
-{
- // File attributes for use with the FileEnumerator class.
- // These constants correspond to the constants in WinNT.h.
- [Serializable]
- [Flags]
- [System.Runtime.InteropServices.ComVisible(true)]
- public enum FileAttributes
- {
- // From WinNT.h (FILE_ATTRIBUTE_XXX)
- ReadOnly = 0x1,
- Hidden = 0x2,
- System = 0x4,
- Directory = 0x10,
- Archive = 0x20,
- Device = 0x40,
- Normal = 0x80,
- Temporary = 0x100,
- SparseFile = 0x200,
- ReparsePoint = 0x400,
- Compressed = 0x800,
- Offline = 0x1000,
- NotContentIndexed = 0x2000,
- Encrypted = 0x4000,
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Win32Native = Microsoft.Win32.Win32Native;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Runtime.Serialization;
-using System.Globalization;
-using System.Runtime.Versioning;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.IO
-{
- // Class for creating FileStream objects, and some basic file management
- // routines such as Delete, etc.
- [Serializable]
- [ComVisible(true)]
- public sealed class FileInfo: FileSystemInfo
- {
- private String _name;
-
- // Migrating InheritanceDemands requires this default ctor, so we can annotate it.
- private FileInfo(){}
-
- public FileInfo(String fileName)
- {
- if (fileName == null)
- throw new ArgumentNullException(nameof(fileName));
- Contract.EndContractBlock();
-
- Init(fileName);
- }
-
- private void Init(String fileName)
- {
- OriginalPath = fileName;
- _name = Path.GetFileName(fileName);
- FullPath = Path.GetFullPath(fileName);
- DisplayPath = GetDisplayPath(fileName);
- }
-
- private String GetDisplayPath(String originalPath)
- {
- return Path.GetFileName(originalPath);
- }
-
- private FileInfo(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- _name = Path.GetFileName(OriginalPath);
- DisplayPath = GetDisplayPath(OriginalPath);
- }
-
- internal FileInfo(String fullPath, bool ignoreThis)
- {
- Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
- _name = Path.GetFileName(fullPath);
- OriginalPath = _name;
- FullPath = fullPath;
- DisplayPath = _name;
- }
-
- public override String Name {
- get { return _name; }
- }
-
- public long Length {
- get {
- if (_dataInitialised == -1)
- Refresh();
-
- if (_dataInitialised != 0) // Refresh was unable to initialise the data
- __Error.WinIOError(_dataInitialised, DisplayPath);
-
- if ((_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0)
- __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, DisplayPath);
-
- return ((long)_data.fileSizeHigh) << 32 | ((long)_data.fileSizeLow & 0xFFFFFFFFL);
- }
- }
-
- /* Returns the name of the directory that the file is in */
- public String DirectoryName
- {
- get
- {
- return Path.GetDirectoryName(FullPath);
- }
- }
-
- /* Creates an instance of the the parent directory */
- public DirectoryInfo Directory
- {
- get
- {
- String dirName = DirectoryName;
- if (dirName == null)
- return null;
- return new DirectoryInfo(dirName);
- }
- }
-
- public bool IsReadOnly {
- get {
- return (Attributes & FileAttributes.ReadOnly) != 0;
- }
- set {
- if (value)
- Attributes |= FileAttributes.ReadOnly;
- else
- Attributes &= ~FileAttributes.ReadOnly;
- }
- }
-
- public StreamReader OpenText()
- {
- return new StreamReader(FullPath, Encoding.UTF8, true, StreamReader.DefaultBufferSize);
- }
-
- public StreamWriter CreateText()
- {
- return new StreamWriter(FullPath,false);
- }
-
- public StreamWriter AppendText()
- {
- return new StreamWriter(FullPath,true);
- }
-
- // Copies an existing file to a new file. An exception is raised if the
- // destination file already exists. Use the
- // Copy(String, String, boolean) method to allow
- // overwriting an existing file.
- public FileInfo CopyTo(String destFileName) {
- if (destFileName == null)
- throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
- Contract.EndContractBlock();
-
- destFileName = File.InternalCopy(FullPath, destFileName, false);
- return new FileInfo(destFileName, false);
- }
-
- // Copies an existing file to a new file. If overwrite is
- // false, then an IOException is thrown if the destination file
- // already exists. If overwrite is true, the file is
- // overwritten.
- public FileInfo CopyTo(String destFileName, bool overwrite) {
- if (destFileName == null)
- throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
- if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
- Contract.EndContractBlock();
-
- destFileName = File.InternalCopy(FullPath, destFileName, overwrite);
- return new FileInfo(destFileName, false);
- }
-
- public FileStream Create() {
- return File.Create(FullPath);
- }
-
- // Deletes a file. The file specified by the designated path is deleted.
- // If the file does not exist, Delete succeeds without throwing
- // an exception.
- //
- // On NT, Delete will fail for a file that is open for normal I/O
- // or a file that is memory mapped.
- public override void Delete()
- {
- bool r = Win32Native.DeleteFile(FullPath);
- if (!r) {
- int hr = Marshal.GetLastWin32Error();
- if (hr==Win32Native.ERROR_FILE_NOT_FOUND)
- return;
- else
- __Error.WinIOError(hr, DisplayPath);
- }
- }
-
- // Tests if the given file exists. The result is true if the file
- // given by the specified path exists; otherwise, the result is
- // false.
- public override bool Exists {
- get {
- try {
- if (_dataInitialised == -1)
- Refresh();
- if (_dataInitialised != 0) {
- // Refresh was unable to initialise the data.
- // We should normally be throwing an exception here,
- // but Exists is supposed to return true or false.
- return false;
- }
- return (_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0;
- }
- catch
- {
- return false;
- }
- }
- }
-
- // User must explicitly specify opening a new file or appending to one.
- public FileStream Open(FileMode mode) {
- return Open(mode, FileAccess.ReadWrite, FileShare.None);
- }
-
- public FileStream Open(FileMode mode, FileAccess access) {
- return Open(mode, access, FileShare.None);
- }
-
- public FileStream Open(FileMode mode, FileAccess access, FileShare share) {
- return new FileStream(FullPath, mode, access, share);
- }
-
- public FileStream OpenRead()
- {
- return new FileStream(FullPath, FileMode.Open, FileAccess.Read,
- FileShare.Read, 4096, false);
- }
-
- public FileStream OpenWrite() {
- return new FileStream(FullPath, FileMode.OpenOrCreate,
- FileAccess.Write, FileShare.None);
- }
-
- // Moves a given file to a new location and potentially a new file name.
- // This method does work across volumes.
- public void MoveTo(String destFileName) {
- if (destFileName==null)
- throw new ArgumentNullException(nameof(destFileName));
- if (destFileName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
- Contract.EndContractBlock();
-
- string fullDestFileName = Path.GetFullPath(destFileName);
-
- if (!Win32Native.MoveFile(FullPath, fullDestFileName))
- __Error.WinIOError();
- FullPath = fullDestFileName;
- OriginalPath = destFileName;
- _name = Path.GetFileName(fullDestFileName);
- DisplayPath = GetDisplayPath(destFileName);
- // Flush any cached information about the file.
- _dataInitialised = -1;
- }
-
- [ComVisible(false)]
- public FileInfo Replace(String destinationFileName, String destinationBackupFileName)
- {
- return Replace(destinationFileName, destinationBackupFileName, false);
- }
-
- [ComVisible(false)]
- public FileInfo Replace(String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors)
- {
- File.Replace(FullPath, destinationFileName, destinationBackupFileName, ignoreMetadataErrors);
- return new FileInfo(destinationFileName);
- }
-
- // Returns the display path
- public override String ToString()
- {
- return DisplayPath;
- }
- }
-}
namespace System.IO
{
-
// Overview:
// The key methods instantiate FileSystemEnumerableIterators. These compose the iterator with search result
// handlers that instantiate the FileInfo, DirectoryInfo, String, etc. The handlers then perform any
SearchResultHandler<String> handler = new StringResultHandler(includeFiles, includeDirs);
return new FileSystemEnumerableIterator<String>(path, originalUserPath, searchPattern, searchOption, handler, checkHost);
}
-
- internal static IEnumerable<FileInfo> CreateFileInfoIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(originalUserPath != null);
- Contract.Requires(searchPattern != null);
-
- SearchResultHandler<FileInfo> handler = new FileInfoResultHandler();
- return new FileSystemEnumerableIterator<FileInfo>(path, originalUserPath, searchPattern, searchOption, handler, true);
- }
-
- internal static IEnumerable<DirectoryInfo> CreateDirectoryInfoIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption)
- {
-
- Contract.Requires(path != null);
- Contract.Requires(originalUserPath != null);
- Contract.Requires(searchPattern != null);
-
- SearchResultHandler<DirectoryInfo> handler = new DirectoryInfoResultHandler();
- return new FileSystemEnumerableIterator<DirectoryInfo>(path, originalUserPath, searchPattern, searchOption, handler, true);
- }
-
- internal static IEnumerable<FileSystemInfo> CreateFileSystemInfoIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption)
- {
- Contract.Requires(path != null);
- Contract.Requires(originalUserPath != null);
- Contract.Requires(searchPattern != null);
-
- SearchResultHandler<FileSystemInfo> handler = new FileSystemInfoResultHandler();
- return new FileSystemEnumerableIterator<FileSystemInfo>(path, originalUserPath, searchPattern, searchOption, handler, true);
- }
}
// Abstract Iterator, borrowed from Linq. Used in anticipation of need for similar enumerables
private String searchCriteria;
SafeFindHandle _hnd = null;
- // empty means we know in advance that we won\92t find any search results, which can happen if:
- // 1. we don\92t have a search pattern
- // 2. we\92re enumerating only the top directory and found no matches during the first call
- // This flag allows us to return early for these cases. We can\92t know this in advance for
- // SearchOption.AllDirectories because we do a \93*\94 search for subdirs and then use the
+ // empty means we know in advance that we won't find any search results, which can happen if:
+ // 1. we don't have a search pattern
+ // 2. we're enumerating only the top directory and found no matches during the first call
+ // This flag allows us to return early for these cases. We can't know this in advance for
+ // SearchOption.AllDirectories because we do a "*" search for subdirs and then use the
// searchPattern at each directory level.
bool empty;
}
}
- internal class FileInfoResultHandler : SearchResultHandler<FileInfo>
- {
- internal override bool IsResultIncluded(SearchResult result)
- {
- return FileSystemEnumerableHelpers.IsFile(result.FindData);
- }
-
- internal override FileInfo CreateObject(SearchResult result)
- {
- String name = result.FullPath;
- FileInfo fi = new FileInfo(name, false);
- fi.InitializeFrom(result.FindData);
- return fi;
- }
- }
-
- internal class DirectoryInfoResultHandler : SearchResultHandler<DirectoryInfo>
- {
- internal override bool IsResultIncluded(SearchResult result)
- {
- return FileSystemEnumerableHelpers.IsDir(result.FindData);
- }
-
- internal override DirectoryInfo CreateObject(SearchResult result)
- {
- DirectoryInfo di = new DirectoryInfo(result.FullPath, false);
- di.InitializeFrom(result.FindData);
- return di;
- }
- }
-
- internal class FileSystemInfoResultHandler : SearchResultHandler<FileSystemInfo>
- {
-
- internal override bool IsResultIncluded(SearchResult result)
- {
- bool includeFile = FileSystemEnumerableHelpers.IsFile(result.FindData);
- bool includeDir = FileSystemEnumerableHelpers.IsDir(result.FindData);
- Debug.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!");
-
- return (includeDir || includeFile);
- }
-
- internal override FileSystemInfo CreateObject(SearchResult result)
- {
- bool isFile = FileSystemEnumerableHelpers.IsFile(result.FindData);
- bool isDir = FileSystemEnumerableHelpers.IsDir(result.FindData);
-
- if (isDir)
- {
- DirectoryInfo di = new DirectoryInfo(result.FullPath, false);
- di.InitializeFrom(result.FindData);
- return di;
- }
- else
- {
- Contract.Assert(isFile);
- FileInfo fi = new FileInfo(result.FullPath, false);
- fi.InitializeFrom(result.FindData);
- return fi;
- }
- }
-
- }
-
internal sealed class SearchResult
{
private String fullPath; // fully-qualifed path
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Microsoft.Win32;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Diagnostics.Contracts;
-
-namespace System.IO
-{
-#if FEATURE_SERIALIZATION
- [Serializable]
-#endif
- [ComVisible(true)]
- public abstract class FileSystemInfo : MarshalByRefObject, ISerializable {
-
- internal Win32Native.WIN32_FILE_ATTRIBUTE_DATA _data; // Cache the file information
- internal int _dataInitialised = -1; // We use this field in conjunction with the Refresh methods, if we succeed
- // we store a zero, on failure we store the HResult in it so that we can
- // give back a generic error back.
-
- private const int ERROR_INVALID_PARAMETER = 87;
- internal const int ERROR_ACCESS_DENIED = 0x5;
-
- protected String FullPath; // fully qualified path of the directory
- protected String OriginalPath; // path passed in by the user
- private String _displayPath = ""; // path that can be displayed to the user
-
- protected FileSystemInfo()
- {
- }
-
- protected FileSystemInfo(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Must use V1 field names here, since V1 didn't implement
- // ISerializable.
- FullPath = Path.GetFullPath(info.GetString("FullPath"));
- OriginalPath = info.GetString("OriginalPath");
-
- // Lazily initialize the file attributes.
- _dataInitialised = -1;
- }
-
- internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData)
- {
- _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- _data.PopulateFrom(findData);
- _dataInitialised = 0;
- }
-
- // Full path of the direcory/file
- public virtual String FullName {
- get
- {
- return FullPath;
- }
- }
-
- public String Extension
- {
- get
- {
- // GetFullPathInternal would have already stripped out the terminating "." if present.
- int length = FullPath.Length;
- for (int i = length; --i >= 0;) {
- char ch = FullPath[i];
- if (ch == '.')
- return FullPath.Substring(i, length - i);
- if (ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar || ch == Path.VolumeSeparatorChar)
- break;
- }
- return String.Empty;
- }
- }
-
- // For files name of the file is returned, for directories the last directory in hierarchy is returned if possible,
- // otherwise the fully qualified name s returned
- public abstract String Name {
- get;
- }
-
- // Whether a file/directory exists
- public abstract bool Exists
- {
- get;
- }
-
- // Delete a file/directory
- public abstract void Delete();
-
- public DateTime CreationTime
- {
- get {
- // depends on the security check in get_CreationTimeUtc
- return CreationTimeUtc.ToLocalTime();
- }
- }
-
- [ComVisible(false)]
- public DateTime CreationTimeUtc {
- get {
- if (_dataInitialised == -1) {
- _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- Refresh();
- }
-
- if (_dataInitialised != 0) // Refresh was unable to initialise the data
- __Error.WinIOError(_dataInitialised, DisplayPath);
-
- long fileTime = ((long)_data.ftCreationTimeHigh << 32) | _data.ftCreationTimeLow;
- return DateTime.FromFileTimeUtc(fileTime);
-
- }
- }
-
- public DateTime LastAccessTime
- {
- get {
- // depends on the security check in get_LastAccessTimeUtc
- return LastAccessTimeUtc.ToLocalTime();
- }
- set {
- LastAccessTimeUtc = value.ToUniversalTime();
- }
- }
-
- [ComVisible(false)]
- public DateTime LastAccessTimeUtc {
- get {
- if (_dataInitialised == -1) {
- _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- Refresh();
- }
-
- if (_dataInitialised != 0) // Refresh was unable to initialise the data
- __Error.WinIOError(_dataInitialised, DisplayPath);
-
- long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow;
- return DateTime.FromFileTimeUtc(fileTime);
- }
-
- set {
- }
- }
-
- public DateTime LastWriteTime
- {
- get {
- // depends on the security check in get_LastWriteTimeUtc
- return LastWriteTimeUtc.ToLocalTime();
- }
-
- set {
- LastWriteTimeUtc = value.ToUniversalTime();
- }
- }
-
- [ComVisible(false)]
- public DateTime LastWriteTimeUtc {
- get {
- if (_dataInitialised == -1) {
- _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- Refresh();
- }
-
- if (_dataInitialised != 0) // Refresh was unable to initialise the data
- __Error.WinIOError(_dataInitialised, DisplayPath);
-
-
- long fileTime = ((long)_data.ftLastWriteTimeHigh << 32) | _data.ftLastWriteTimeLow;
- return DateTime.FromFileTimeUtc(fileTime);
- }
-
- set {
- }
- }
-
- public void Refresh()
- {
- _dataInitialised = File.FillAttributeInfo(FullPath, ref _data, false, false);
- }
-
- public FileAttributes Attributes {
- get
- {
- if (_dataInitialised == -1) {
- _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- Refresh(); // Call refresh to intialise the data
- }
-
- if (_dataInitialised != 0) // Refresh was unable to initialise the data
- __Error.WinIOError(_dataInitialised, DisplayPath);
-
- return (FileAttributes) _data.fileAttributes;
- }
-
- set {
- bool r = Win32Native.SetFileAttributes(FullPath, (int) value);
- if (!r) {
- int hr = Marshal.GetLastWin32Error();
-
- if (hr==ERROR_INVALID_PARAMETER)
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs"));
-
- // For whatever reason we are turning ERROR_ACCESS_DENIED into
- // ArgumentException here (probably done for some 9x code path).
- // We can't change this now but special casing the error message instead.
- if (hr == ERROR_ACCESS_DENIED)
- throw new ArgumentException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
- __Error.WinIOError(hr, DisplayPath);
- }
- _dataInitialised = -1;
- }
- }
-
- [ComVisible(false)]
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- info.AddValue("OriginalPath", OriginalPath, typeof(String));
- info.AddValue("FullPath", FullPath, typeof(String));
- }
-
- internal String DisplayPath
- {
- get
- {
- return _displayPath;
- }
- set
- {
- _displayPath = value;
- }
- }
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-using System;
-using System.Diagnostics.Contracts;
-using System.Runtime.Versioning;
-using System.Text;
-
-namespace System.IO
-{
- // An iterator that returns a single line at-a-time from a given file.
- //
- // Known issues which cannot be changed to remain compatible with 4.0:
- //
- // - The underlying StreamReader is allocated upfront for the IEnumerable<T> before
- // GetEnumerator has even been called. While this is good in that exceptions such as
- // DirectoryNotFoundException and FileNotFoundException are thrown directly by
- // File.ReadLines (which the user probably expects), it also means that the reader
- // will be leaked if the user never actually foreach's over the enumerable (and hence
- // calls Dispose on at least one IEnumerator<T> instance).
- //
- // - Reading to the end of the IEnumerator<T> disposes it. This means that Dispose
- // is called twice in a normal foreach construct.
- //
- // - IEnumerator<T> instances from the same IEnumerable<T> party on the same underlying
- // reader (Dev10 Bugs 904764).
- //
- internal class ReadLinesIterator : Iterator<string>
- {
- private readonly string _path;
- private readonly Encoding _encoding;
- private StreamReader _reader;
-
- private ReadLinesIterator(string path, Encoding encoding, StreamReader reader)
- {
- Contract.Requires(path != null);
- Contract.Requires(path.Length > 0);
- Contract.Requires(encoding != null);
- Contract.Requires(reader != null);
-
- _path = path;
- _encoding = encoding;
- _reader = reader;
- }
-
- public override bool MoveNext()
- {
- if (this._reader != null)
- {
- this.current = _reader.ReadLine();
- if (this.current != null)
- return true;
-
- // To maintain 4.0 behavior we Dispose
- // after reading to the end of the reader.
- Dispose();
- }
-
- return false;
- }
-
- protected override Iterator<string> Clone()
- {
- // NOTE: To maintain the same behavior with the previous yield-based
- // iterator in 4.0, we have all the IEnumerator<T> instances share the same
- // underlying reader. If we have already been disposed, _reader will be null,
- // which will cause CreateIterator to simply new up a new instance to start up
- // a new iteration. Dev10 Bugs 904764 has been filed to fix this in next side-
- // by-side release.
- return CreateIterator(_path, _encoding, _reader);
- }
-
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing)
- {
- if (_reader != null)
- {
- _reader.Dispose();
- }
- }
- }
- finally
- {
- _reader = null;
- base.Dispose(disposing);
- }
- }
-
- internal static ReadLinesIterator CreateIterator(string path, Encoding encoding)
- {
- return CreateIterator(path, encoding, (StreamReader)null);
- }
-
- private static ReadLinesIterator CreateIterator(string path, Encoding encoding, StreamReader reader)
- {
- return new ReadLinesIterator(path, encoding, reader ?? new StreamReader(path, encoding));
- }
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Text;
-using System.Runtime.CompilerServices;
-using System.Security.Permissions;
-using System.Runtime.Serialization;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace System.IO
-{
- // This class implements a TextWriter for writing characters to a Stream.
- // This is designed for character output in a particular Encoding,
- // whereas the Stream class is designed for byte input and output.
- //
- [Serializable]
- [ComVisible(true)]
- public class StreamWriter : TextWriter
- {
- // For UTF-8, the values of 1K for the default buffer size and 4K for the
- // file stream buffer size are reasonable & give very reasonable
- // performance for in terms of construction time for the StreamWriter and
- // write perf. Note that for UTF-8, we end up allocating a 4K byte buffer,
- // which means we take advantage of adaptive buffering code.
- // The performance using UnicodeEncoding is acceptable.
- internal const int DefaultBufferSize = 1024; // char[]
- private const int DefaultFileStreamBufferSize = 4096;
- private const int MinBufferSize = 128;
-
- // Bit bucket - Null has no backing store. Non closable.
- public new static readonly StreamWriter Null = new StreamWriter(Stream.Null, UTF8NoBOM, MinBufferSize, true);
-
- private Stream stream;
- private Encoding encoding;
- private Encoder encoder;
- private byte[] byteBuffer;
- private char[] charBuffer;
- private int charPos;
- private int charLen;
- private bool autoFlush;
- private bool haveWrittenPreamble;
- private bool closable;
-
- // We don't guarantee thread safety on StreamWriter, but we should at
- // least prevent users from trying to write anything while an Async
- // write from the same thread is in progress.
- [NonSerialized]
- private volatile Task _asyncWriteTask;
-
- private void CheckAsyncTaskInProgress()
- {
- // We are not locking the access to _asyncWriteTask because this is not meant to guarantee thread safety.
- // We are simply trying to deter calling any Write APIs while an async Write from the same thread is in progress.
-
- Task t = _asyncWriteTask;
-
- if (t != null && !t.IsCompleted)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncIOInProgress"));
- }
-
- // The high level goal is to be tolerant of encoding errors when we read and very strict
- // when we write. Hence, default StreamWriter encoding will throw on encoding error.
- // Note: when StreamWriter throws on invalid encoding chars (for ex, high surrogate character
- // D800-DBFF without a following low surrogate character DC00-DFFF), it will cause the
- // internal StreamWriter's state to be irrecoverable as it would have buffered the
- // illegal chars and any subsequent call to Flush() would hit the encoding error again.
- // Even Close() will hit the exception as it would try to flush the unwritten data.
- // Maybe we can add a DiscardBufferedData() method to get out of such situation (like
- // StreamReader though for different reason). Either way, the buffered data will be lost!
- internal static Encoding UTF8NoBOM {
- [FriendAccessAllowed]
- get { return EncodingCache.UTF8NoBOM; }
- }
-
-
- internal StreamWriter(): base(null) { // Ask for CurrentCulture all the time
- }
-
- public StreamWriter(Stream stream)
- : this(stream, UTF8NoBOM, DefaultBufferSize, false) {
- }
-
- public StreamWriter(Stream stream, Encoding encoding)
- : this(stream, encoding, DefaultBufferSize, false) {
- }
-
- // Creates a new StreamWriter for the given stream. The
- // character encoding is set by encoding and the buffer size,
- // in number of 16-bit characters, is set by bufferSize.
- //
- public StreamWriter(Stream stream, Encoding encoding, int bufferSize)
- : this(stream, encoding, bufferSize, false) {
- }
-
- public StreamWriter(Stream stream, Encoding encoding, int bufferSize, bool leaveOpen)
- : base(null) // Ask for CurrentCulture all the time
- {
- if (stream == null || encoding == null)
- throw new ArgumentNullException((stream == null ? nameof(stream) : nameof(encoding)));
- if (!stream.CanWrite)
- throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable"));
- if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
- Contract.EndContractBlock();
-
- Init(stream, encoding, bufferSize, leaveOpen);
- }
-
- public StreamWriter(String path)
- : this(path, false, UTF8NoBOM, DefaultBufferSize) {
- }
-
- public StreamWriter(String path, bool append)
- : this(path, append, UTF8NoBOM, DefaultBufferSize) {
- }
-
- public StreamWriter(String path, bool append, Encoding encoding)
- : this(path, append, encoding, DefaultBufferSize) {
- }
-
- public StreamWriter(String path, bool append, Encoding encoding, int bufferSize)
- : base(null)
- {
- // Ask for CurrentCulture all the time
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (encoding == null)
- throw new ArgumentNullException(nameof(encoding));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
- Contract.EndContractBlock();
-
- Stream stream = CreateFile(path, append);
- Init(stream, encoding, bufferSize, false);
- }
-
- private void Init(Stream streamArg, Encoding encodingArg, int bufferSize, bool shouldLeaveOpen)
- {
- this.stream = streamArg;
- this.encoding = encodingArg;
- this.encoder = encoding.GetEncoder();
- if (bufferSize < MinBufferSize) bufferSize = MinBufferSize;
- charBuffer = new char[bufferSize];
- byteBuffer = new byte[encoding.GetMaxByteCount(bufferSize)];
- charLen = bufferSize;
- // If we're appending to a Stream that already has data, don't write
- // the preamble.
- if (stream.CanSeek && stream.Position > 0)
- haveWrittenPreamble = true;
- closable = !shouldLeaveOpen;
- }
-
- private static Stream CreateFile(String path, bool append) {
- FileMode mode = append? FileMode.Append: FileMode.Create;
- FileStream f = new FileStream(path, mode, FileAccess.Write, FileShare.Read,
- DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false);
- return f;
- }
-
- public override void Close() {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected override void Dispose(bool disposing) {
- try {
- // We need to flush any buffered data if we are being closed/disposed.
- // Also, we never close the handles for stdout & friends. So we can safely
- // write any buffered data to those streams even during finalization, which
- // is generally the right thing to do.
- if (stream != null) {
- // Note: flush on the underlying stream can throw (ex., low disk space)
- if (disposing)
- {
- CheckAsyncTaskInProgress();
-
- Flush(true, true);
- }
- }
- }
- finally {
- // Dispose of our resources if this StreamWriter is closable.
- // Note: Console.Out and other such non closable streamwriters should be left alone
- if (!LeaveOpen && stream != null) {
- try {
- // Attempt to close the stream even if there was an IO error from Flushing.
- // Note that Stream.Close() can potentially throw here (may or may not be
- // due to the same Flush error). In this case, we still need to ensure
- // cleaning up internal resources, hence the finally block.
- if (disposing)
- stream.Close();
- }
- finally {
- stream = null;
- byteBuffer = null;
- charBuffer = null;
- encoding = null;
- encoder = null;
- charLen = 0;
- base.Dispose(disposing);
- }
- }
- }
- }
-
- public override void Flush()
- {
- CheckAsyncTaskInProgress();
-
- Flush(true, true);
- }
-
- private void Flush(bool flushStream, bool flushEncoder)
- {
- // flushEncoder should be true at the end of the file and if
- // the user explicitly calls Flush (though not if AutoFlush is true).
- // This is required to flush any dangling characters from our UTF-7
- // and UTF-8 encoders.
- if (stream == null)
- __Error.WriterClosed();
-
- // Perf boost for Flush on non-dirty writers.
- if (charPos==0 && (!flushStream && !flushEncoder))
- return;
-
- if (!haveWrittenPreamble) {
- haveWrittenPreamble = true;
- byte[] preamble = encoding.GetPreamble();
- if (preamble.Length > 0)
- stream.Write(preamble, 0, preamble.Length);
- }
-
- int count = encoder.GetBytes(charBuffer, 0, charPos, byteBuffer, 0, flushEncoder);
- charPos = 0;
- if (count > 0)
- stream.Write(byteBuffer, 0, count);
- // By definition, calling Flush should flush the stream, but this is
- // only necessary if we passed in true for flushStream. The Web
- // Services guys have some perf tests where flushing needlessly hurts.
- if (flushStream)
- stream.Flush();
- }
-
- public virtual bool AutoFlush {
- get { return autoFlush; }
-
- set
- {
- CheckAsyncTaskInProgress();
-
- autoFlush = value;
- if (value) Flush(true, false);
- }
- }
-
- public virtual Stream BaseStream {
- get { return stream; }
- }
-
- internal bool LeaveOpen {
- get { return !closable; }
- }
-
- internal bool HaveWrittenPreamble {
- set { haveWrittenPreamble= value; }
- }
-
- public override Encoding Encoding {
- get { return encoding; }
- }
-
- public override void Write(char value)
- {
- CheckAsyncTaskInProgress();
-
- if (charPos == charLen) Flush(false, false);
- charBuffer[charPos] = value;
- charPos++;
- if (autoFlush) Flush(true, false);
- }
-
- public override void Write(char[] buffer)
- {
- // This may be faster than the one with the index & count since it
- // has to do less argument checking.
- if (buffer==null)
- return;
-
- CheckAsyncTaskInProgress();
-
- int index = 0;
- int count = buffer.Length;
- while (count > 0) {
- if (charPos == charLen) Flush(false, false);
- int n = charLen - charPos;
- if (n > count) n = count;
- Debug.Assert(n > 0, "StreamWriter::Write(char[]) isn't making progress! This is most likely a race condition in user code.");
- Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char));
- charPos += n;
- index += n;
- count -= n;
- }
- if (autoFlush) Flush(true, false);
- }
-
- public override void Write(char[] buffer, int index, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- CheckAsyncTaskInProgress();
-
- while (count > 0) {
- if (charPos == charLen) Flush(false, false);
- int n = charLen - charPos;
- if (n > count) n = count;
- Debug.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code.");
- Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char));
- charPos += n;
- index += n;
- count -= n;
- }
- if (autoFlush) Flush(true, false);
- }
-
- public override void Write(String value)
- {
- if (value != null)
- {
-
- CheckAsyncTaskInProgress();
-
- int count = value.Length;
- int index = 0;
- while (count > 0) {
- if (charPos == charLen) Flush(false, false);
- int n = charLen - charPos;
- if (n > count) n = count;
- Debug.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code.");
- value.CopyTo(index, charBuffer, charPos, n);
- charPos += n;
- index += n;
- count -= n;
- }
- if (autoFlush) Flush(true, false);
- }
- }
-
- #region Task based Async APIs
- [ComVisible(false)]
- public override Task WriteAsync(char value)
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteAsync(value);
-
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: false);
- _asyncWriteTask = task;
-
- return task;
- }
-
- // We pass in private instance fields of this MarshalByRefObject-derived type as local params
- // to ensure performant access inside the state machine that corresponds this async method.
- // Fields that are written to must be assigned at the end of the method *and* before instance invocations.
- private static async Task WriteAsyncInternal(StreamWriter _this, Char value,
- Char[] charBuffer, Int32 charPos, Int32 charLen, Char[] coreNewLine,
- bool autoFlush, bool appendNewLine)
- {
- if (charPos == charLen) {
- await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- charBuffer[charPos] = value;
- charPos++;
-
- if (appendNewLine)
- {
- for (Int32 i = 0; i < coreNewLine.Length; i++) // Expect 2 iterations, no point calling BlockCopy
- {
- if (charPos == charLen) {
- await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- charBuffer[charPos] = coreNewLine[i];
- charPos++;
- }
- }
-
- if (autoFlush) {
- await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- _this.CharPos_Prop = charPos;
- }
-
- [ComVisible(false)]
- public override Task WriteAsync(String value)
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteAsync(value);
-
- if (value != null)
- {
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: false);
- _asyncWriteTask = task;
-
- return task;
- }
- else
- {
- return Task.CompletedTask;
- }
- }
-
- // We pass in private instance fields of this MarshalByRefObject-derived type as local params
- // to ensure performant access inside the state machine that corresponds this async method.
- // Fields that are written to must be assigned at the end of the method *and* before instance invocations.
- private static async Task WriteAsyncInternal(StreamWriter _this, String value,
- Char[] charBuffer, Int32 charPos, Int32 charLen, Char[] coreNewLine,
- bool autoFlush, bool appendNewLine)
- {
- Contract.Requires(value != null);
-
- int count = value.Length;
- int index = 0;
-
- while (count > 0)
- {
- if (charPos == charLen) {
- await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- int n = charLen - charPos;
- if (n > count)
- n = count;
-
- Debug.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code.");
-
- value.CopyTo(index, charBuffer, charPos, n);
-
- charPos += n;
- index += n;
- count -= n;
- }
-
- if (appendNewLine)
- {
- for (Int32 i = 0; i < coreNewLine.Length; i++) // Expect 2 iterations, no point calling BlockCopy
- {
- if (charPos == charLen) {
- await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- charBuffer[charPos] = coreNewLine[i];
- charPos++;
- }
- }
-
- if (autoFlush) {
- await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- _this.CharPos_Prop = charPos;
- }
-
- [ComVisible(false)]
- public override Task WriteAsync(char[] buffer, int index, int count)
- {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteAsync(buffer, index, count);
-
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, buffer, index, count, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: false);
- _asyncWriteTask = task;
-
- return task;
- }
-
- // We pass in private instance fields of this MarshalByRefObject-derived type as local params
- // to ensure performant access inside the state machine that corresponds this async method.
- // Fields that are written to must be assigned at the end of the method *and* before instance invocations.
- private static async Task WriteAsyncInternal(StreamWriter _this, Char[] buffer, Int32 index, Int32 count,
- Char[] charBuffer, Int32 charPos, Int32 charLen, Char[] coreNewLine,
- bool autoFlush, bool appendNewLine)
- {
- Contract.Requires(count == 0 || (count > 0 && buffer != null));
- Contract.Requires(index >= 0);
- Contract.Requires(count >= 0);
- Contract.Requires(buffer == null || (buffer != null && buffer.Length - index >= count));
-
- while (count > 0)
- {
- if (charPos == charLen) {
- await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- int n = charLen - charPos;
- if (n > count) n = count;
-
- Debug.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code.");
-
- Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char));
-
- charPos += n;
- index += n;
- count -= n;
- }
-
- if (appendNewLine)
- {
- for (Int32 i = 0; i < coreNewLine.Length; i++) // Expect 2 iterations, no point calling BlockCopy
- {
- if (charPos == charLen) {
- await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- charBuffer[charPos] = coreNewLine[i];
- charPos++;
- }
- }
-
- if (autoFlush) {
- await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false);
- Debug.Assert(_this.charPos == 0);
- charPos = 0;
- }
-
- _this.CharPos_Prop = charPos;
- }
-
- [ComVisible(false)]
- public override Task WriteLineAsync()
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteLineAsync();
-
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, null, 0, 0, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true);
- _asyncWriteTask = task;
-
- return task;
- }
-
-
- [ComVisible(false)]
- public override Task WriteLineAsync(char value)
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteLineAsync(value);
-
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true);
- _asyncWriteTask = task;
-
- return task;
- }
-
-
- [ComVisible(false)]
- public override Task WriteLineAsync(String value)
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteLineAsync(value);
-
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true);
- _asyncWriteTask = task;
-
- return task;
- }
-
-
- [ComVisible(false)]
- public override Task WriteLineAsync(char[] buffer, int index, int count)
- {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.WriteLineAsync(buffer, index, count);
-
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = WriteAsyncInternal(this, buffer, index, count, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true);
- _asyncWriteTask = task;
-
- return task;
- }
-
-
- [ComVisible(false)]
- public override Task FlushAsync()
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Flush() which a subclass might have overriden. To be safe
- // we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Flush) when we are not sure.
- if (this.GetType() != typeof(StreamWriter))
- return base.FlushAsync();
-
- // flushEncoder should be true at the end of the file and if
- // the user explicitly calls Flush (though not if AutoFlush is true).
- // This is required to flush any dangling characters from our UTF-7
- // and UTF-8 encoders.
- if (stream == null)
- __Error.WriterClosed();
-
- CheckAsyncTaskInProgress();
-
- Task task = FlushAsyncInternal(true, true, charBuffer, charPos);
- _asyncWriteTask = task;
-
- return task;
- }
-
- private Int32 CharPos_Prop {
- set { this.charPos = value; }
- }
-
- private bool HaveWrittenPreamble_Prop {
- set { this.haveWrittenPreamble = value; }
- }
-
- private Task FlushAsyncInternal(bool flushStream, bool flushEncoder,
- Char[] sCharBuffer, Int32 sCharPos) {
-
- // Perf boost for Flush on non-dirty writers.
- if (sCharPos == 0 && !flushStream && !flushEncoder)
- return Task.CompletedTask;
-
- Task flushTask = FlushAsyncInternal(this, flushStream, flushEncoder, sCharBuffer, sCharPos, this.haveWrittenPreamble,
- this.encoding, this.encoder, this.byteBuffer, this.stream);
-
- this.charPos = 0;
- return flushTask;
- }
-
-
- // We pass in private instance fields of this MarshalByRefObject-derived type as local params
- // to ensure performant access inside the state machine that corresponds this async method.
- private static async Task FlushAsyncInternal(StreamWriter _this, bool flushStream, bool flushEncoder,
- Char[] charBuffer, Int32 charPos, bool haveWrittenPreamble,
- Encoding encoding, Encoder encoder, Byte[] byteBuffer, Stream stream)
- {
- if (!haveWrittenPreamble)
- {
- _this.HaveWrittenPreamble_Prop = true;
- byte[] preamble = encoding.GetPreamble();
- if (preamble.Length > 0)
- await stream.WriteAsync(preamble, 0, preamble.Length).ConfigureAwait(false);
- }
-
- int count = encoder.GetBytes(charBuffer, 0, charPos, byteBuffer, 0, flushEncoder);
- if (count > 0)
- await stream.WriteAsync(byteBuffer, 0, count).ConfigureAwait(false);
-
- // By definition, calling Flush should flush the stream, but this is
- // only necessary if we passed in true for flushStream. The Web
- // Services guys have some perf tests where flushing needlessly hurts.
- if (flushStream)
- await stream.FlushAsync().ConfigureAwait(false);
- }
- #endregion
- } // class StreamWriter
-} // namespace
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Text;
-using System.Threading;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Security.Permissions;
-using System.Globalization;
-using System.Diagnostics.CodeAnalysis;
-using System.Diagnostics.Contracts;
-using System.Threading.Tasks;
-
-namespace System.IO {
- // This abstract base class represents a writer that can write a sequential
- // stream of characters. A subclass must minimally implement the
- // Write(char) method.
- //
- // This class is intended for character output, not bytes.
- // There are methods on the Stream class for writing bytes.
- [Serializable]
- [ComVisible(true)]
- public abstract class TextWriter : MarshalByRefObject, IDisposable {
- public static readonly TextWriter Null = new NullTextWriter();
-
- // This should be initialized to Environment.NewLine, but
- // to avoid loading Environment unnecessarily so I've duplicated
- // the value here.
-#if !PLATFORM_UNIX
- private const String InitialNewLine = "\r\n";
-
- protected char[] CoreNewLine = new char[] { '\r', '\n' };
-#else
- private const String InitialNewLine = "\n";
-
- protected char[] CoreNewLine = new char[] {'\n'};
-#endif // !PLATFORM_UNIX
-
- // Can be null - if so, ask for the Thread's CurrentCulture every time.
- private IFormatProvider InternalFormatProvider;
-
- protected TextWriter()
- {
- InternalFormatProvider = null; // Ask for CurrentCulture all the time.
- }
-
- protected TextWriter(IFormatProvider formatProvider)
- {
- InternalFormatProvider = formatProvider;
- }
-
- public virtual IFormatProvider FormatProvider {
- get {
- if (InternalFormatProvider == null)
- return Thread.CurrentThread.CurrentCulture;
- else
- return InternalFormatProvider;
- }
- }
-
- // Closes this TextWriter and releases any system resources associated with the
- // TextWriter. Following a call to Close, any operations on the TextWriter
- // may raise exceptions. This default method is empty, but descendant
- // classes can override the method to provide the appropriate
- // functionality.
- public virtual void Close() {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- }
-
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- // Clears all buffers for this TextWriter and causes any buffered data to be
- // written to the underlying device. This default method is empty, but
- // descendant classes can override the method to provide the appropriate
- // functionality.
- public virtual void Flush() {
- }
-
- public abstract Encoding Encoding {
- get;
- }
-
- // Returns the line terminator string used by this TextWriter. The default line
- // terminator string is a carriage return followed by a line feed ("\r\n").
- //
- // Sets the line terminator string for this TextWriter. The line terminator
- // string is written to the text stream whenever one of the
- // WriteLine methods are called. In order for text written by
- // the TextWriter to be readable by a TextReader, only one of the following line
- // terminator strings should be used: "\r", "\n", or "\r\n".
- //
- public virtual String NewLine {
- get { return new String(CoreNewLine); }
- set {
- if (value == null)
- value = InitialNewLine;
- CoreNewLine = value.ToCharArray();
- }
- }
-
-
- public static TextWriter Synchronized(TextWriter writer) {
- if (writer==null)
- throw new ArgumentNullException(nameof(writer));
- Contract.Ensures(Contract.Result<TextWriter>() != null);
- Contract.EndContractBlock();
-
- if (writer is SyncTextWriter)
- return writer;
-
- return new SyncTextWriter(writer);
- }
-
- // Writes a character to the text stream. This default method is empty,
- // but descendant classes can override the method to provide the
- // appropriate functionality.
- //
- public virtual void Write(char value) {
- }
-
- // Writes a character array to the text stream. This default method calls
- // Write(char) for each of the characters in the character array.
- // If the character array is null, nothing is written.
- //
- public virtual void Write(char[] buffer) {
- if (buffer != null) Write(buffer, 0, buffer.Length);
- }
-
- // Writes a range of a character array to the text stream. This method will
- // write count characters of data into this TextWriter from the
- // buffer character array starting at position index.
- //
- public virtual void Write(char[] buffer, int index, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- for (int i = 0; i < count; i++) Write(buffer[index + i]);
- }
-
- // Writes the text representation of a boolean to the text stream. This
- // method outputs either Boolean.TrueString or Boolean.FalseString.
- //
- public virtual void Write(bool value) {
- Write(value ? Boolean.TrueLiteral : Boolean.FalseLiteral);
- }
-
- // Writes the text representation of an integer to the text stream. The
- // text representation of the given value is produced by calling the
- // Int32.ToString() method.
- //
- public virtual void Write(int value) {
- Write(value.ToString(FormatProvider));
- }
-
- // Writes the text representation of an integer to the text stream. The
- // text representation of the given value is produced by calling the
- // UInt32.ToString() method.
- //
- [CLSCompliant(false)]
- public virtual void Write(uint value) {
- Write(value.ToString(FormatProvider));
- }
-
- // Writes the text representation of a long to the text stream. The
- // text representation of the given value is produced by calling the
- // Int64.ToString() method.
- //
- public virtual void Write(long value) {
- Write(value.ToString(FormatProvider));
- }
-
- // Writes the text representation of an unsigned long to the text
- // stream. The text representation of the given value is produced
- // by calling the UInt64.ToString() method.
- //
- [CLSCompliant(false)]
- public virtual void Write(ulong value) {
- Write(value.ToString(FormatProvider));
- }
-
- // Writes the text representation of a float to the text stream. The
- // text representation of the given value is produced by calling the
- // Float.toString(float) method.
- //
- public virtual void Write(float value) {
- Write(value.ToString(FormatProvider));
- }
-
- // Writes the text representation of a double to the text stream. The
- // text representation of the given value is produced by calling the
- // Double.toString(double) method.
- //
- public virtual void Write(double value) {
- Write(value.ToString(FormatProvider));
- }
-
- public virtual void Write(Decimal value) {
- Write(value.ToString(FormatProvider));
- }
-
- // Writes a string to the text stream. If the given string is null, nothing
- // is written to the text stream.
- //
- public virtual void Write(String value) {
- if (value != null) Write(value.ToCharArray());
- }
-
- // Writes the text representation of an object to the text stream. If the
- // given object is null, nothing is written to the text stream.
- // Otherwise, the object's ToString method is called to produce the
- // string representation, and the resulting string is then written to the
- // output stream.
- //
- public virtual void Write(Object value) {
- if (value != null) {
- IFormattable f = value as IFormattable;
- if (f != null)
- Write(f.ToString(null, FormatProvider));
- else
- Write(value.ToString());
- }
- }
-
-#if false
- // // Converts the wchar * to a string and writes this to the stream.
- // //
- // __attribute NonCLSCompliantAttribute()
- // public void Write(wchar *value) {
- // Write(new String(value));
- // }
-
- // // Treats the byte* as a LPCSTR, converts it to a string, and writes it to the stream.
- // //
- // __attribute NonCLSCompliantAttribute()
- // public void Write(byte *value) {
- // Write(new String(value));
- // }
-#endif
-
-
- // Writes out a formatted string. Uses the same semantics as
- // String.Format.
- //
- public virtual void Write(String format, Object arg0)
- {
- Write(String.Format(FormatProvider, format, arg0));
- }
-
- // Writes out a formatted string. Uses the same semantics as
- // String.Format.
- //
- public virtual void Write(String format, Object arg0, Object arg1)
- {
- Write(String.Format(FormatProvider, format, arg0, arg1));
- }
-
- // Writes out a formatted string. Uses the same semantics as
- // String.Format.
- //
- public virtual void Write(String format, Object arg0, Object arg1, Object arg2)
- {
- Write(String.Format(FormatProvider, format, arg0, arg1, arg2));
- }
-
- // Writes out a formatted string. Uses the same semantics as
- // String.Format.
- //
- public virtual void Write(String format, params Object[] arg)
- {
- Write(String.Format(FormatProvider, format, arg));
- }
-
-
- // Writes a line terminator to the text stream. The default line terminator
- // is a carriage return followed by a line feed ("\r\n"), but this value
- // can be changed by setting the NewLine property.
- //
- public virtual void WriteLine() {
- Write(CoreNewLine);
- }
-
- // Writes a character followed by a line terminator to the text stream.
- //
- public virtual void WriteLine(char value) {
- Write(value);
- WriteLine();
- }
-
- // Writes an array of characters followed by a line terminator to the text
- // stream.
- //
- public virtual void WriteLine(char[] buffer) {
- Write(buffer);
- WriteLine();
- }
-
- // Writes a range of a character array followed by a line terminator to the
- // text stream.
- //
- public virtual void WriteLine(char[] buffer, int index, int count) {
- Write(buffer, index, count);
- WriteLine();
- }
-
- // Writes the text representation of a boolean followed by a line
- // terminator to the text stream.
- //
- public virtual void WriteLine(bool value) {
- Write(value);
- WriteLine();
- }
-
- // Writes the text representation of an integer followed by a line
- // terminator to the text stream.
- //
- public virtual void WriteLine(int value) {
- Write(value);
- WriteLine();
- }
-
- // Writes the text representation of an unsigned integer followed by
- // a line terminator to the text stream.
- //
- [CLSCompliant(false)]
- public virtual void WriteLine(uint value) {
- Write(value);
- WriteLine();
- }
-
- // Writes the text representation of a long followed by a line terminator
- // to the text stream.
- //
- public virtual void WriteLine(long value) {
- Write(value);
- WriteLine();
- }
-
- // Writes the text representation of an unsigned long followed by
- // a line terminator to the text stream.
- //
- [CLSCompliant(false)]
- public virtual void WriteLine(ulong value) {
- Write(value);
- WriteLine();
- }
-
- // Writes the text representation of a float followed by a line terminator
- // to the text stream.
- //
- public virtual void WriteLine(float value) {
- Write(value);
- WriteLine();
- }
-
- // Writes the text representation of a double followed by a line terminator
- // to the text stream.
- //
- public virtual void WriteLine(double value) {
- Write(value);
- WriteLine();
- }
-
- public virtual void WriteLine(decimal value) {
- Write(value);
- WriteLine();
- }
-
- // Writes a string followed by a line terminator to the text stream.
- //
- public virtual void WriteLine(String value) {
-
- if (value==null) {
- WriteLine();
- }
- else {
- // We'd ideally like WriteLine to be atomic, in that one call
- // to WriteLine equals one call to the OS (ie, so writing to
- // console while simultaneously calling printf will guarantee we
- // write out a string and new line chars, without any interference).
- // Additionally, we need to call ToCharArray on Strings anyways,
- // so allocating a char[] here isn't any worse than what we were
- // doing anyways. We do reduce the number of calls to the
- // backing store this way, potentially.
- int vLen = value.Length;
- int nlLen = CoreNewLine.Length;
- char[] chars = new char[vLen+nlLen];
- value.CopyTo(0, chars, 0, vLen);
- // CoreNewLine will almost always be 2 chars, and possibly 1.
- if (nlLen == 2) {
- chars[vLen] = CoreNewLine[0];
- chars[vLen+1] = CoreNewLine[1];
- }
- else if (nlLen == 1)
- chars[vLen] = CoreNewLine[0];
- else
- Buffer.InternalBlockCopy(CoreNewLine, 0, chars, vLen * 2, nlLen * 2);
- Write(chars, 0, vLen + nlLen);
- }
- /*
- Write(value); // We could call Write(String) on StreamWriter...
- WriteLine();
- */
- }
-
- // Writes the text representation of an object followed by a line
- // terminator to the text stream.
- //
- public virtual void WriteLine(Object value) {
- if (value==null) {
- WriteLine();
- }
- else {
- // Call WriteLine(value.ToString), not Write(Object), WriteLine().
- // This makes calls to WriteLine(Object) atomic.
- IFormattable f = value as IFormattable;
- if (f != null)
- WriteLine(f.ToString(null, FormatProvider));
- else
- WriteLine(value.ToString());
- }
- }
-
- // Writes out a formatted string and a new line. Uses the same
- // semantics as String.Format.
- //
- public virtual void WriteLine(String format, Object arg0)
- {
- WriteLine(String.Format(FormatProvider, format, arg0));
- }
-
- // Writes out a formatted string and a new line. Uses the same
- // semantics as String.Format.
- //
- public virtual void WriteLine (String format, Object arg0, Object arg1)
- {
- WriteLine(String.Format(FormatProvider, format, arg0, arg1));
- }
-
- // Writes out a formatted string and a new line. Uses the same
- // semantics as String.Format.
- //
- public virtual void WriteLine (String format, Object arg0, Object arg1, Object arg2)
- {
- WriteLine(String.Format(FormatProvider, format, arg0, arg1, arg2));
- }
-
- // Writes out a formatted string and a new line. Uses the same
- // semantics as String.Format.
- //
- public virtual void WriteLine (String format, params Object[] arg)
- {
- WriteLine(String.Format(FormatProvider, format, arg));
- }
-
- #region Task based Async APIs
- [ComVisible(false)]
- public virtual Task WriteAsync(char value)
- {
- var tuple = new Tuple<TextWriter, char>(this, value);
- return Task.Factory.StartNew(state =>
- {
- var t = (Tuple<TextWriter, char>)state;
- t.Item1.Write(t.Item2);
- },
- tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
-
- [ComVisible(false)]
- public virtual Task WriteAsync(String value)
- {
- var tuple = new Tuple<TextWriter, string>(this, value);
- return Task.Factory.StartNew(state =>
- {
- var t = (Tuple<TextWriter, string>)state;
- t.Item1.Write(t.Item2);
- },
- tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
-
- [ComVisible(false)]
- public Task WriteAsync(char[] buffer)
- {
- if (buffer == null) return Task.CompletedTask;
- return WriteAsync(buffer, 0, buffer.Length);
- }
-
- [ComVisible(false)]
- public virtual Task WriteAsync(char[] buffer, int index, int count)
- {
- var tuple = new Tuple<TextWriter, char[], int, int>(this, buffer, index, count);
- return Task.Factory.StartNew(state =>
- {
- var t = (Tuple<TextWriter, char[], int, int>)state;
- t.Item1.Write(t.Item2, t.Item3, t.Item4);
- },
- tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
-
- [ComVisible(false)]
- public virtual Task WriteLineAsync(char value)
- {
- var tuple = new Tuple<TextWriter, char>(this, value);
- return Task.Factory.StartNew(state =>
- {
- var t = (Tuple<TextWriter, char>)state;
- t.Item1.WriteLine(t.Item2);
- },
- tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
-
- [ComVisible(false)]
- public virtual Task WriteLineAsync(String value)
- {
- var tuple = new Tuple<TextWriter, string>(this, value);
- return Task.Factory.StartNew(state =>
- {
- var t = (Tuple<TextWriter, string>)state;
- t.Item1.WriteLine(t.Item2);
- },
- tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
-
- [ComVisible(false)]
- public Task WriteLineAsync(char[] buffer)
- {
- if (buffer == null) return Task.CompletedTask;
- return WriteLineAsync(buffer, 0, buffer.Length);
- }
-
- [ComVisible(false)]
- public virtual Task WriteLineAsync(char[] buffer, int index, int count)
- {
- var tuple = new Tuple<TextWriter, char[], int, int>(this, buffer, index, count);
- return Task.Factory.StartNew(state =>
- {
- var t = (Tuple<TextWriter, char[], int, int>)state;
- t.Item1.WriteLine(t.Item2, t.Item3, t.Item4);
- },
- tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
-
- [ComVisible(false)]
- public virtual Task WriteLineAsync()
- {
- return WriteAsync(CoreNewLine);
- }
-
- [ComVisible(false)]
- public virtual Task FlushAsync()
- {
- return Task.Factory.StartNew(state =>
- {
- ((TextWriter)state).Flush();
- },
- this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
- }
- #endregion
-
- [Serializable]
- private sealed class NullTextWriter : TextWriter
- {
- internal NullTextWriter(): base(CultureInfo.InvariantCulture) {
- }
-
- public override Encoding Encoding {
- get { return Encoding.Default; }
- }
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override void Write(char[] buffer, int index, int count) {
- }
-
- public override void Write(String value) {
- }
-
- // Not strictly necessary, but for perf reasons
- public override void WriteLine() {
- }
-
- // Not strictly necessary, but for perf reasons
- public override void WriteLine(String value) {
- }
-
- public override void WriteLine(Object value) {
- }
- }
-
- [Serializable]
- internal sealed class SyncTextWriter : TextWriter, IDisposable
- {
- private TextWriter _out;
-
- internal SyncTextWriter(TextWriter t): base(t.FormatProvider) {
- _out = t;
- }
-
- public override Encoding Encoding {
- get { return _out.Encoding; }
- }
-
- public override IFormatProvider FormatProvider {
- get { return _out.FormatProvider; }
- }
-
- public override String NewLine {
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- get { return _out.NewLine; }
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- set { _out.NewLine = value; }
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Close() {
- // So that any overriden Close() gets run
- _out.Close();
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- protected override void Dispose(bool disposing) {
- // Explicitly pick up a potentially methodimpl'ed Dispose
- if (disposing)
- ((IDisposable)_out).Dispose();
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Flush() {
- _out.Flush();
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(char value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(char[] buffer) {
- _out.Write(buffer);
- }
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(char[] buffer, int index, int count) {
- _out.Write(buffer, index, count);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(bool value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(int value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(uint value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(long value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(ulong value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(float value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(double value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(Decimal value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(String value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(Object value) {
- _out.Write(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(String format, Object arg0) {
- _out.Write(format, arg0);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(String format, Object arg0, Object arg1) {
- _out.Write(format, arg0, arg1);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(String format, Object arg0, Object arg1, Object arg2) {
- _out.Write(format, arg0, arg1, arg2);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void Write(String format, Object[] arg) {
- _out.Write(format, arg);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine() {
- _out.WriteLine();
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(char value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(decimal value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(char[] buffer) {
- _out.WriteLine(buffer);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(char[] buffer, int index, int count) {
- _out.WriteLine(buffer, index, count);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(bool value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(int value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(uint value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(long value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(ulong value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(float value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(double value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(String value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(Object value) {
- _out.WriteLine(value);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(String format, Object arg0) {
- _out.WriteLine(format, arg0);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(String format, Object arg0, Object arg1) {
- _out.WriteLine(format, arg0, arg1);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(String format, Object arg0, Object arg1, Object arg2) {
- _out.WriteLine(format, arg0, arg1, arg2);
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- public override void WriteLine(String format, Object[] arg) {
- _out.WriteLine(format, arg);
- }
-
-
- //
- // On SyncTextWriter all APIs should run synchronously, even the async ones.
- //
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task WriteAsync(char value)
- {
- Write(value);
- return Task.CompletedTask;
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task WriteAsync(String value)
- {
- Write(value);
- return Task.CompletedTask;
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task WriteAsync(char[] buffer, int index, int count)
- {
- Write(buffer, index, count);
- return Task.CompletedTask;
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task WriteLineAsync(char value)
- {
- WriteLine(value);
- return Task.CompletedTask;
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task WriteLineAsync(String value)
- {
- WriteLine(value);
- return Task.CompletedTask;
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task WriteLineAsync(char[] buffer, int index, int count)
- {
- WriteLine(buffer, index, count);
- return Task.CompletedTask;
- }
-
- [MethodImplAttribute(MethodImplOptions.Synchronized)]
- [ComVisible(false)]
- public override Task FlushAsync()
- {
- Flush();
- return Task.CompletedTask;
- }
- }
- }
-}