【问题标题】:File.Copy versus read and write in C#File.Copy 与 C# 中的读取和写入
【发布时间】:2013-06-07 10:48:14
【问题描述】:

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

我有两个选择

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

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

谢谢

【问题讨论】:

  • 你自己的假设是什么
  • 如果选项 2 更好,微软为什么不将其用作File.Copy的实现?

标签: c#


【解决方案1】:

选择第一个选项。 因为它是一个内置函数,将使用 CPU 而不是内存

StreamReader 将使用内存,当您有大文件时应避免使用。然而,缓冲也可以在此实现。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2020-05-23
        • 2015-07-26
        • 2020-04-16
        • 1970-01-01
        • 2017-07-22
        • 1970-01-01
        • 2013-05-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多