我必须实现一个功能,其中文件需要从一个位置复制并且应该粘贴到另一个位置(同一服务器上其他驱动器中的某个文件夹)。
我有两个选择
1. Implement file.copy functionality.
2. Read the file using StreamReader and the create and write destination file.
任何人都可以确认哪个选项会更好,性能更明智,更不容易出错和复制失败。
谢谢
我必须实现一个功能,其中文件需要从一个位置复制并且应该粘贴到另一个位置(同一服务器上其他驱动器中的某个文件夹)。
我有两个选择
1. Implement file.copy functionality.
2. Read the file using StreamReader and the create and write destination file.
任何人都可以确认哪个选项会更好,性能更明智,更不容易出错和复制失败。
谢谢
选择第一个选项。因为它是一个内置功能,将使用 CPU 而不是内存
StreamReader 将使用内存,当您有大文件时应避免使用。然而,缓冲也可以在其中实现。
File.Copy 将完成这项工作。除非我想说一个进度条,否则不会说 FileStream 去 StreamReader。
正如您在 Reflector 中看到的那样,File.Copy 使用本机 Windows 方法来创建副本。我认为从一个流中读取字节并写入另一个流会更快。
public static void Copy(string sourceFileName, string destFileName)
{
if (sourceFileName == null)
{
throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
}
if (destFileName == null)
{
throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
}
if (sourceFileName.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
}
if (destFileName.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
}
InternalCopy(sourceFileName, destFileName, false, true);
}
InternalCopy 方法的内容是:
[SecuritySafeCritical]
internal static string InternalCopy(string sourceFileName, string destFileName, bool overwrite, bool checkHost)
{
string fullPathInternal = Path.GetFullPathInternal(sourceFileName);
string dst = Path.GetFullPathInternal(destFileName);
new FileIOPermission(FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
new FileIOPermission(FileIOPermissionAccess.Write, new string[] { dst }, false, false).Demand();
if (!Win32Native.CopyFile(fullPathInternal, dst, !overwrite))
{
int errorCode = Marshal.GetLastWin32Error();
string maybeFullPath = destFileName;
if (errorCode != 80)
{
using (SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullPathInternal, -2147483648, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero))
{
if (handle.IsInvalid)
{
maybeFullPath = sourceFileName;
}
}
if ((errorCode == 5) && Directory.InternalExists(dst))
{
throw new IOException(Environment.GetResourceString("Arg_FileIsDirectory_Name", new object[] { destFileName }), 5, dst);
}
}
__Error.WinIOError(errorCode, maybeFullPath);
}
return dst;
}