复制文件Ex“参数无效”错误
本文关键字:参数无效 错误 无效 参数 文件 Ex 复制 | 更新日期: 2023-09-27 18:32:41
我正在使用.NET 4编写一个(相当(简单的C#应用程序,以便在运行可执行文件之前检查更新。如果网络共享上存在较新版本的 exe,只需将其复制到本地文件夹并启动它即可。这一切都运行良好,除了在阅读 File.Copy(( 的限制时,我意识到当我这样做时我将无法显示进度条,我看到的所有内容都说使用 CopyFileEx,所以我正在尝试这样做。
我使用了这里找到的示例代码,它编译得很好(尽管我仍然有点不确定后台工作者是如何发挥作用的(,除非当我实际运行应用程序时,CopyFilEx(( 方法返回 false,错误是"参数不正确"。
我的代码(仅相关部分,如果需要,我会添加更多(
调用函数:
XCopy.Copy(strServerAppPath + strExeName, strLocalAppPath + strExeName, true, true, (o, pce) =>
{
worker.ReportProgress(pce.ProgressPercentage, strServerAppPath + strExeName);
});
(源路径的计算结果为"C:''test.txt",目标路径的计算结果为"C:''test''test.txt"(
如果上面链接的代码中出现错误:
bool result = CopyFileEx(Source, Destination, new CopyProgressRoutine(CopyProgressHandler), IntPtr.Zero, ref IsCancelled, copyFileFlags);
if (!result)
throw new Win32Exception(Marshal.GetLastWin32Error());
提前感谢您的帮助,我已经为此苦苦挣扎了几个小时......
与其处理所有这些编组,不如"滚动自己的"复印机,逐块进行
:private static void CopyFile(string source, string destination, int bytesPerChunk)
{
int bytesRead = 0;
using (FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fs))
{
using (FileStream fsDest = new FileStream(destination, FileMode.Create))
{
BinaryWriter bw = new BinaryWriter(fsDest);
byte[] buffer;
for (int i = 0; i < fs.Length; i += bytesPerChunk)
{
buffer = br.ReadBytes(bytesPerChunk);
bw.Write(buffer);
bytesRead += bytesPerChunk;
ReportProgress(bytesRead, fs.Length); //report the progress
}
}
}
}
}
不是调用 ReadBytes()
,后者在每次调用时分配一个新的byte[]
缓冲区数组,而是分配一个缓冲区(例如大小为 64KB(并调用 Read(buf, 0, buf.Length)
,这将读取多达 buf.Length
个字节到数组中,然后返回读取的实际字节数。然后,在每次读取时重复使用相同的缓冲区数组(将其内容写出到目标流后(。这样就不必为每个读/写操作重新分配新的缓冲区。
例
例如,流复制方法的内部循环如下所示:
byte[] buf;
// Allocate an I/O data buffer
buf = new byte[64*1024];
// Copy the contents of the input stream to the output stream
for (;;)
{
int len;
// Read a block of data from the input stream
len = inp.ReadBytes(buf, 0, buf.Length);
if (len <= 0)
break;
// Write the data to the output stream
outp.Write(buf, 0, len);
}
循环将最多 64KB 的字节从输入流读入缓冲区,然后将读取到输出流的实际字节数写出。每个读/写操作使用相同的缓冲区,因此我们不会对缓冲区进行不必要的分配和解除分配。当读取操作失败时,我们已经到达了输入流的末尾,因此我们退出循环。