文件复制程序无法正确复制文件
File Copy Program Doesn't Properly Copy File
你好
我一直在开发类似终端的应用程序,以便更好地使用 C# 进行编程,这只是帮助我学习的东西。我决定添加一项功能,将文件原样复制到新文件中……它似乎工作得近乎完美。在 Notepad++ 中打开时,文件的长度仅相隔几行,而且与实际文件大小非常非常接近。但是,该文件的副本永远不会运行。它说文件已损坏。我有一种感觉,它在读取和重写二进制文件到我创建的文件的方法中。代码如下,感谢帮助。也对意大利面条代码感到抱歉,当我胡思乱想新想法时,我有点马虎。
Class 处理文件 copying/writing
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++;
}
}
}
}
与此交互的代码 class .
(Sleep(5000) 是因为我预计第一次尝试会出错...
case '3':
Console.Write("Enter source file: ");
string sourceFile = Console.ReadLine();
if (sourceFile == "")
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Error.WriteLine("Must input a proper file path.\n");
Console.ForegroundColor = ConsoleColor.White;
Menu();
} else {
Console.WriteLine("Copying Data"); System.Threading.Thread.Sleep(5000);
FileTransfer trans = new FileTransfer(sourceFile);
//copying the original files data
byte[] data = trans.ReadAllDataToArray();
Console.Write("Enter Location to store data: ");
string newPath = Console.ReadLine();
// Just for me to make sure it doesnt exit if i forget
if(newPath == "")
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Error.WriteLine("Cannot have empty path.");
Console.ForegroundColor = ConsoleColor.White;
Menu();
} else
{
Console.WriteLine("Writing data to file"); System.Threading.Thread.Sleep(5000);
trans.WriteDataFromArray(data, newPath);
Console.WriteLine("File stored.");
Console.ReadLine();
Console.Clear();
Menu();
}
}
break;
文件与新文件比较
右键单击 -> 在新选项卡中打开可能是个好主意
C#中有一个File.Copy()方法,你可以在这里看到https://msdn.microsoft.com/ru-ru/library/c6cfw35a(v=vs.110).aspx
如果你想自己实现,尝试在你的方法中放置一个断点并使用调试。这就像一个关于渔夫和上帝的故事,上帝给了渔夫一根鱼竿——得到了一条鱼,而不是真正的鱼。
此外,看看你最后一个方法中的 int[] fileData 和 byte[] fileData,也许这是问题所在。
您没有正确处理文件流和二进制编写器。两者都倾向于缓冲数据(这是一件好事,尤其是当您一次写入 一个字节时 )。使用 using
,您的问题应该会消失。当然,除非有人在您阅读文件时正在编辑文件。
BinaryReader
和BinaryWriter
不要只写"raw data"。它们还根据需要添加元数据——它们专为序列化和反序列化而设计,而不是读取和写入字节。现在,在使用 ReadBytes
和 Write(byte[])
的特殊情况下,这些实际上只是原始字节;但是仅仅为此使用这些 类 没有多大意义。读取和写入字节是 每个 Stream
给你的东西 - 这包括 FileStream
s。没有理由在这里使用 BinaryReader
/BinaryWriter
无论如何 - 文件流为您提供所需的一切。
更好的方法是简单地使用
using (var fsn = ...)
{
fsn.Write(fileData, 0, fileData.Length);
}
甚至只是
File.WriteAllBytes(fileName, fileData);
也许您认为一次写入一个字节更接近 "the metal",但事实并非如此。在此期间,CPU 绝不会一次将一个字节传递给硬盘驱动器。相反,硬盘 直接从 RAM 复制数据,没有 CPU 的干预。而且大多数硬盘驱动器仍然无法从物理介质写入(或读取)任意数量的数据——相反,您正在读取和写入整个扇区。如果系统确实一次写入一个字节,那么您将一遍又一遍地重写同一个扇区,只是为了再写入一个字节。
更好的方法是利用您已打开文件流这一事实,将文件从源流式传输到目标,而不是先将所有内容读入内存,然后再将其写回磁盘。
你好
我一直在开发类似终端的应用程序,以便更好地使用 C# 进行编程,这只是帮助我学习的东西。我决定添加一项功能,将文件原样复制到新文件中……它似乎工作得近乎完美。在 Notepad++ 中打开时,文件的长度仅相隔几行,而且与实际文件大小非常非常接近。但是,该文件的副本永远不会运行。它说文件已损坏。我有一种感觉,它在读取和重写二进制文件到我创建的文件的方法中。代码如下,感谢帮助。也对意大利面条代码感到抱歉,当我胡思乱想新想法时,我有点马虎。
Class 处理文件 copying/writing
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++;
}
}
}
}
与此交互的代码 class .
(Sleep(5000) 是因为我预计第一次尝试会出错...
case '3':
Console.Write("Enter source file: ");
string sourceFile = Console.ReadLine();
if (sourceFile == "")
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Error.WriteLine("Must input a proper file path.\n");
Console.ForegroundColor = ConsoleColor.White;
Menu();
} else {
Console.WriteLine("Copying Data"); System.Threading.Thread.Sleep(5000);
FileTransfer trans = new FileTransfer(sourceFile);
//copying the original files data
byte[] data = trans.ReadAllDataToArray();
Console.Write("Enter Location to store data: ");
string newPath = Console.ReadLine();
// Just for me to make sure it doesnt exit if i forget
if(newPath == "")
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Error.WriteLine("Cannot have empty path.");
Console.ForegroundColor = ConsoleColor.White;
Menu();
} else
{
Console.WriteLine("Writing data to file"); System.Threading.Thread.Sleep(5000);
trans.WriteDataFromArray(data, newPath);
Console.WriteLine("File stored.");
Console.ReadLine();
Console.Clear();
Menu();
}
}
break;
文件与新文件比较 右键单击 -> 在新选项卡中打开可能是个好主意
C#中有一个File.Copy()方法,你可以在这里看到https://msdn.microsoft.com/ru-ru/library/c6cfw35a(v=vs.110).aspx
如果你想自己实现,尝试在你的方法中放置一个断点并使用调试。这就像一个关于渔夫和上帝的故事,上帝给了渔夫一根鱼竿——得到了一条鱼,而不是真正的鱼。
此外,看看你最后一个方法中的 int[] fileData 和 byte[] fileData,也许这是问题所在。
您没有正确处理文件流和二进制编写器。两者都倾向于缓冲数据(这是一件好事,尤其是当您一次写入 一个字节时 )。使用 using
,您的问题应该会消失。当然,除非有人在您阅读文件时正在编辑文件。
BinaryReader
和BinaryWriter
不要只写"raw data"。它们还根据需要添加元数据——它们专为序列化和反序列化而设计,而不是读取和写入字节。现在,在使用 ReadBytes
和 Write(byte[])
的特殊情况下,这些实际上只是原始字节;但是仅仅为此使用这些 类 没有多大意义。读取和写入字节是 每个 Stream
给你的东西 - 这包括 FileStream
s。没有理由在这里使用 BinaryReader
/BinaryWriter
无论如何 - 文件流为您提供所需的一切。
更好的方法是简单地使用
using (var fsn = ...)
{
fsn.Write(fileData, 0, fileData.Length);
}
甚至只是
File.WriteAllBytes(fileName, fileData);
也许您认为一次写入一个字节更接近 "the metal",但事实并非如此。在此期间,CPU 绝不会一次将一个字节传递给硬盘驱动器。相反,硬盘 直接从 RAM 复制数据,没有 CPU 的干预。而且大多数硬盘驱动器仍然无法从物理介质写入(或读取)任意数量的数据——相反,您正在读取和写入整个扇区。如果系统确实一次写入一个字节,那么您将一遍又一遍地重写同一个扇区,只是为了再写入一个字节。
更好的方法是利用您已打开文件流这一事实,将文件从源流式传输到目标,而不是先将所有内容读入内存,然后再将其写回磁盘。