File.Copy与C#中的读写

时间:2013-06-07 10:48:15

标签: c#

我必须实现一个功能,需要从一个位置复制文件,并将其粘贴到另一个位置(同一服务器上其他驱动器中的某个文件夹)。

我有两个选择

1. Implement file.copy functionality.
2. Read the file using StreamReader and the create and write  destination file.

任何人都可以确认哪个选项更好,性能更好,更不容易出错和复制失败。

由于

3 个答案:

答案 0 :(得分:3)

选择第一个选项。 因为它的内置功能会使用CPU而不是内存

StreamReader将使用内存,当你有大文件时应该避免使用。但是,缓冲也可以在此实现。

答案 1 :(得分:0)

File.Copy将完成这项工作。不会用FileStream去StreamReader,除非我想说进度条。

答案 2 :(得分:0)

正如您在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;
}