C# 文件复制程序没有';无法正确复制文件

C# 文件复制程序没有';无法正确复制文件,c#,filestream,binaryreader,binarywriter,C#,Filestream,Binaryreader,Binarywriter,你好 我一直在研究类似于终端的应用程序,以便更好地用c#编程,这只是帮助我学习的东西。我决定添加一个功能,将文件复制到一个新文件中。。。它似乎工作得近乎完美。在Notepad++中打开时,文件的长度仅相隔几行,并且非常非常接近实际文件大小。但是,文件的复制副本永远不会运行。它说文件已损坏。我有一种感觉,就是在我创建的文件中读取和重写二进制文件的方法中。代码如下,谢谢您的帮助。我也为意大利面代码感到抱歉,当我和新的想法混在一起时,我会有点马虎 处理文件复制/写入的类 using System; u

你好

我一直在研究类似于终端的应用程序,以便更好地用c#编程,这只是帮助我学习的东西。我决定添加一个功能,将文件复制到一个新文件中。。。它似乎工作得近乎完美。在Notepad++中打开时,文件的长度仅相隔几行,并且非常非常接近实际文件大小。但是,文件的复制副本永远不会运行。它说文件已损坏。我有一种感觉,就是在我创建的文件中读取和重写二进制文件的方法中。代码如下,谢谢您的帮助。我也为意大利面代码感到抱歉,当我和新的想法混在一起时,我会有点马虎

处理文件复制/写入的类

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);