C# System.IO.File.Copy 问题

C# System.IO.File.Copy issue

所以我需要制作一个快速的 Windows 表单应用程序来处理文件列表及其目录并将它们复制到新目录。通常我会使用批处理文件来执行此操作,例如

@echo off
mkdir "C:\Users\%username%\Desktop\inst"

:A
ping 127.0.0.1 -n 1 > nul
xcopy "C:\Users\%username%\Desktop\M14.0.1512.400-enu-x64.exe" "C:\Users\%username%\Desktop\inst" /y
xcopy "C:\Users\%username%\AppData\Local\Temp\vcredist.exe" "C:\Users\%username%\Desktop\inst" /y

GOTO A

我知道我没有使用最佳实践等,但这是我想出的一个快速脚本来帮助加快我的工作。现在对几个文件执行此操作很好,但我处理的一些应用程序有 40 多个文件需要复制,每次都必须编写批处理文件有点痛苦。

所以我用一个简单的输入字段和一个按钮来启动一个简单的 WF 应用程序。

用户将文件列表(带有路径和目录,例如 C:\foo\bar\hello.txt)放入输入字段,然后应用程序从文本框中取出每一行并将其推入列表在做了一些基本的过滤之后,例如删除 \n、\t、\r 并用双引号封装字符串(如果它们还没有到位)。

new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;

while (run)
{
    foreach (string path in paths)
    {
        Thread.Sleep(100);
        try
        {
            File.Copy(path, dir, true);
        }
        catch (Exception e)
        {
            g.log.WriteToLog("Failed to copy asset: " + e.ToString());

        }
    }
};

}).Start();

当我 运行 这是我在日志中得到的:

//LOGS
21/03/2019 11:25:56  -  Failed to copy asset: System.ArgumentException: Illegal characters in path.   at System.IO.LongPathHelper.Normalize(String path, UInt32 maxPathLength, Boolean checkInvalidCharacters, Boolean expandShortPaths)   at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)   at System.IO.Path.GetFullPathInternal(String path)   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)   at S2_PackagingTool.Application_Extractor.ExtractAssets() in C:\Users\xxxx\Desktop\GitHub\S2-EnvPrepTool\Application_Extractor.cs:line 98
21/03/2019 11:25:56  -  Path: "C:\Program Files\Freedom Scientific\Runtime JAWS.0\jrt.exe" Dir: "C:\Users\xxxx\Desktop\GitHub\S2-EnvPrepTool\bin\Debug\Extracted Assets"

日志中的第二行是路径和目录变量的值转储。

当我 运行 没有 while 循环的代码并手动添加路径和目录时,例如

File.Copy(@"C:\foo\bar\hello.txt", @"C:\hello\world", true);

File.Copy("C:\foo\bar\hello.txt", "C:\hello\world", true);

它工作正常。

过滤方法我也会附上,希望大家看。请记住,这又快又脏,所以是的:

public string QuoteEncapsulationFilter(string s)
{
    s = s.Replace("\n", String.Empty);
    s = s.Replace("\r", String.Empty);
    s = s.Replace("\t", String.Empty);
    s = s.Replace("\", "\\");

    if (!s.Contains("\""))
    {
        s = "\"" + s + "\"";
    }

    return s;
}

我试过到处寻找答案,但没有成功,有人可以解释一下我在这里做错了什么吗?如果您需要我提供更多信息,请告诉我。

谢谢!

您在 File.Copy (string sourceFileName, string destFileName, bool overwrite); 函数中缺少文件名。您的 dir 路径需要文件名。

https://docs.microsoft.com/en-us/dotnet/api/system.io.file.copy?view=netframework-4.7.2

表示如下:

destFileName String The name of the destination file. This cannot be a directory.

编辑: 在评论中回答你的第二个问题:

new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;

while (run)
{
    foreach (string path in paths)
    {
        Thread.Sleep(100);
        try
        {
            var fileName = Path.GetFileName(path); // Get the file name
            var fullDestination = dir + fileName;  // Complete the uri
            File.Copy(path, fullDestination, true);
        }
        catch (Exception e)
        {
            g.log.WriteToLog("Failed to copy asset: " + e.ToString());

        }
    }
};

}).Start();