C# 文件复制程序没有';无法正确复制文件
你好 我一直在研究类似于终端的应用程序,以便更好地用c#编程,这只是帮助我学习的东西。我决定添加一个功能,将文件复制到一个新文件中。。。它似乎工作得近乎完美。在Notepad++中打开时,文件的长度仅相隔几行,并且非常非常接近实际文件大小。但是,文件的复制副本永远不会运行。它说文件已损坏。我有一种感觉,就是在我创建的文件中读取和重写二进制文件的方法中。代码如下,谢谢您的帮助。我也为意大利面代码感到抱歉,当我和新的想法混在一起时,我会有点马虎 处理文件复制/写入的类C# 文件复制程序没有';无法正确复制文件,c#,filestream,binaryreader,binarywriter,C#,Filestream,Binaryreader,Binarywriter,你好 我一直在研究类似于终端的应用程序,以便更好地用c#编程,这只是帮助我学习的东西。我决定添加一个功能,将文件复制到一个新文件中。。。它似乎工作得近乎完美。在Notepad++中打开时,文件的长度仅相隔几行,并且非常非常接近实际文件大小。但是,文件的复制副本永远不会运行。它说文件已损坏。我有一种感觉,就是在我创建的文件中读取和重写二进制文件的方法中。代码如下,谢谢您的帮助。我也为意大利面代码感到抱歉,当我和新的想法混在一起时,我会有点马虎 处理文件复制/写入的类 using System; u
using System;
using System.IO;
//using System.Collections.Generic;
namespace ConsoleFileExplorer
{
class FileTransfer
{
private BinaryWriter writer;
private BinaryReader reader;
private FileStream fsc; // file to be duplicated
private FileStream fsn; // new location of file
int[] fileData;
private string _file;
public FileTransfer(String file)
{
_file = file;
fsc = new FileStream(file, FileMode.Open);
reader = new BinaryReader(fsc);
}
// Reads all the original files data to an array of bytes
public byte[] ReadAllDataToArray()
{
byte[] bytes = reader.ReadBytes((int)fsc.Length); // reading bytes from the original file
return bytes;
}
// writes the array of original byte data to a new file
public void WriteDataFromArray(byte[] fileData, string path) // got a feeling this is the problem :p
{
fsn = new FileStream(path, FileMode.Create);
writer = new BinaryWriter(fsn);
int i = 0;
while(i < fileData.Length)
{
writer.Write(fileData[i]);
i++;
}
}
}
}
文件与新文件的比较
右键单击->在新选项卡中打开可能是个好主意
在C#中有一个File.Copy()方法,您可以在这里看到它
如果您想自己实现它,请尝试在方法中放置断点并使用调试。这就像一个关于渔夫和上帝的故事,上帝给了渔夫一根鱼竿——为了得到一条鱼,而不是真正的鱼
另外,看看上一个方法中的int[]fileData和byte[]fileData,可能这就是问题所在。您没有正确处理文件流和二进制写入程序。两者都倾向于缓冲数据(这是一件好事,尤其是当您一次写入一个字节时)。使用
使用,您的问题就会消失。当然,除非有人在你阅读文件时正在编辑它
BinaryReader
和BinaryWriter
不只是写“原始数据”。它们还根据需要添加元数据——它们是为序列化和反序列化而设计的,而不是读写字节。现在,在使用ReadBytes
和Write(byte[])
的特定情况下,这些实际上只是原始字节;但是仅仅为了这个目的使用这些类没有多大意义。读取和写入字节是每个流
提供给您的东西,其中包括文件流
s。没有理由在这里使用BinaryReader
/BinaryWriter
whatsover-文件流为您提供了所需的一切
更好的方法是简单地使用
using (var fsn = ...)
{
fsn.Write(fileData, 0, fileData.Length);
}
甚至只是
File.WriteAllBytes(fileName, fileData);
也许你认为一次写一个字节更接近“金属”,但事实并非如此。在此期间,CPU每次都不会向硬盘驱动器传递一个字节。相反,硬盘直接从RAM复制数据,而不需要CPU的干预。而且大多数硬盘仍然不能从物理介质中写入(或读取)任意数量的数据——相反,您正在读取和写入整个扇区。如果系统真的一次写入一个字节,您只需不断地重复写入同一扇区,只需再写入一个字节
更好的方法是利用文件流已打开的事实,将文件从源文件流到目标文件流,而不是先将所有内容读入内存,然后再将其写回磁盘。“也许你认为一次写入一个字节更接近金属”有趣,这正是我所想的。我设计这个项目是为了帮助我从错误中吸取更多的教训,并在编程方面取得更好的成绩,所以我尝试用艰苦的方式来完成大部分事情。。。不过我还有一个问题。对所提到的每一个函数调用Close()&Dispose()是否与将其强制到using语句中相同(本质上不是机械地)?我本想把它们放进去,但一定忘了。@CorderroArtz是的,但是如果你有一个定义的范围,最好使用,它更有弹性(试试…最后),并且易于阅读和理解。例如,如果必须在某个字段中保持流的打开状态(在您的情况下这是不必要的,甚至是不可取的),您应该将整个类标记为IDisposable
,并在那里调用相关的Dispose
方法。当然,您可以在父类实例上使用using
(或者,在实现IDisposable
等的类中使用它)。无需调用Close
-Dispose
即可正确关闭所有内容。
File.WriteAllBytes(fileName, fileData);