C# 使用NetworkStream传输文件,然后重建文件失败
我正在尝试通过网络流发送一个文件,并在客户端重建它。我可以正确地(我认为)获取数据,但当我使用BinaryWriter或FileStream对象重新创建文件时,无论我使用何种方法,文件都会在开始时在同一点被切断C# 使用NetworkStream传输文件,然后重建文件失败,c#,.net,tcpclient,networkstream,C#,.net,Tcpclient,Networkstream,我正在尝试通过网络流发送一个文件,并在客户端重建它。我可以正确地(我认为)获取数据,但当我使用BinaryWriter或FileStream对象重新创建文件时,无论我使用何种方法,文件都会在开始时在同一点被切断 private void ReadandSaveFileFromServer(ref TcpClient clientATF,ref NetworkStream currentStream, string locationToSave) { int fileS
private void ReadandSaveFileFromServer(ref TcpClient clientATF,ref NetworkStream currentStream, string locationToSave)
{
int fileSize = 0;
string fileName = "";
fileName = ReadStringFromServer(ref clientATF,ref currentStream);
fileSize = ReadIntFromServer(ref clientATF,ref currentStream);
byte[] fileSent = new byte[fileSize];
if (currentStream.CanRead && clientATF.Connected)
{
currentStream.Read(fileSent, 0, fileSent.Length);
WriteToConsole("Log Recieved");
}
else
{
WriteToConsole("Log Transfer Failed");
}
FileStream fileToCreate = new FileStream(locationToSave + "\\" + fileName, FileMode.Create);
fileToCreate.Seek(0, SeekOrigin.Begin);
fileToCreate.Write(fileSent, 0, fileSent.Length);
fileToCreate.Close();
//binWriter = new BinaryWriter(File.Open(locationToSave + "\\" + fileName, FileMode.Create));
//binWriter.Write(fileSent);
//binWriter.Close();
}
当我逐步检查文件名和文件大小时,它们是正确的。字节[]也已完全填充。关于我下一步能做什么有什么线索吗
先谢谢你
肖恩
编辑!!!:
所以我知道发生了什么。当我从流中读取字符串和Int时,字节数组的长度是256个索引。因此,我对字符串的读取是以int为单位的,这将影响其他区域。需要解决这个问题。首先,您可以使用方便的方法更简单地写入数据。但我怀疑这是问题所在 您假设您可以在一次读取调用中读取所有数据。您忽略了返回值。不要这样做——相反,要读很多遍,直到你读完了所有你想读的东西,或者你到达了流的末尾。看见如果您使用的是.NET4,您可能会发现一种新方法很有用
(顺便说一句,使用
ref
表示您不理解它的真正含义。确保您理解它是非常值得的。)首先,您可以使用方便的方法更简单地编写数据。但我怀疑这是问题所在
您假设您可以在一次读取调用中读取所有数据。您忽略了返回值。不要这样做——相反,要读很多遍,直到你读完了所有你想读的东西,或者你到达了流的末尾。看见如果您使用的是.NET4,您可能会发现一种新方法很有用
(顺便说一句,你使用的
ref
表明你不理解它的真正含义。确保你理解它是非常值得的。)要补充Jon Skeet的答案,你的阅读代码应该是:
int bytesRead;
int readPos = 0;
do
{
bytesRead = currentStream.Read(fileSent, readPos, fileSent.Length);
readPos += bytesRead;
} while (bytesRead > 0);
为了补充Jon Skeet的答案,您的阅读代码应为:
int bytesRead;
int readPos = 0;
do
{
bytesRead = currentStream.Read(fileSent, readPos, fileSent.Length);
readPos += bytesRead;
} while (bytesRead > 0);
如果您正在寻找通过网络发送和接收文件的通用解决方案,您是否考虑过使用?它可能已经解决了您在尝试这样做时遇到的大多数问题
免责声明:我是此库的开发人员之一。如果您正在寻找通过网络发送和接收文件的通用解决方案,您是否考虑过使用?它可能已经解决了您在尝试这样做时遇到的大多数问题
免责声明:我是这个库的开发人员之一。这可以解释为什么文件的开头被切断了吗?同时,传递网络流和连接不是正确的使用方式,因为我不想“复制”,我对对象所做的所有操作都将被全局反映?@Sean p:它们是引用类型。它不会开始复制周围的数据。请阅读我链接到的文章,里面有很多细节。但我希望文件的结尾被有效地切断,而不是开始。如果开始被切断,这表明先前的读取操作有问题。这能解释为什么文件的开始被切断吗?另外,传递网络流和连接不是正确的使用方式,因为我不想要“副本”而我对该对象所做的所有操作都将被全局反映?@Sean P:它们是引用类型。它不会开始复制周围的数据。请阅读我链接到的文章,里面有很多细节。但我希望文件的结尾被有效地切断,而不是开始。如果开始被切断,则表明先前的读取操作有问题。如果需要进一步的帮助,则需要发布ReadStringFromServer和ReadIntFromServer方法。如果需要进一步的帮助,则需要发布ReadStringFromServer和ReadIntFromServer方法。By
do{…}until(bytesRead==0)
Jim的意思是do{…}而(bytesRead>0)
。除非有人在我不看的时候在C#中加了一个do..until语句。@Tergiver:谢谢。你说得对。我的Pascal正在展示(我用Pascal写东西已经好几年了)。。。我将通过do{…}直到(bytesRead==0)
Jim的意思是do{…}而(bytesRead>0)
。除非有人在我不看的时候在C#中加了一个do..until语句。@Tergiver:谢谢。你说得对。我的Pascal正在展示(我用Pascal写东西已经好几年了)。。。我来修理。