2010-09-20 31 views
1

我想通过NetworkStream发送文件并在客户端重新构建它。我可以正确地获取数据(我认为),但是当我使用BinaryWriter或FileStream对象来重新创建文件时,无论使用何种方法,文件在一开始都会被切断。使用NetworkStream传输文件然后重建文件失败

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

    } 

当我逐步检查fileName和fileSize时,它们是正确的。字节[]也完全填充。关于我接下来可以做什么的任何线索?

在此先感谢...

肖恩

编辑!!!:

所以我想通了,发生了什么事。当我读取一个字符串,然后从流中读取Int时,字节数组长度为256个索引。所以我对字符串的读取正在接受整数,然后会打断其他区域。需要弄清楚...

+0

如果您需要进一步的帮助,您需要发布您的ReadStringFromServer和ReadIntFromServer方法。 – 2010-09-20 19:25:44

回答

3

首先,您可以使用便捷方法File.WriteAllBytes来更简单地写入数据。但我怀疑这是问题所在。

你假设你可以读取所有数据在一次调用Read。你忽略了返回值。不要这样做 - 而是多次阅读,直到您阅读了所有您期望的内容,或者您​​已到达流的末尾。请参阅this article for more details。如果您使用的是.NET 4,那么您可能会发现一种新的CopyTo方法。

(顺便说一句,你的ref使用表明,你不明白它的真正意义。这是很值得确保你理解how arguments are passed in C#

+0

这会解释为什么文件的开头被切断? – 2010-09-20 15:59:49

+0

也不是通过网络流和连接正确的方式来使用它,因为我不想要一个“副本”,我对该对象采取的所有行动将反映在全球? – 2010-09-20 19:49:02

+1

@Sean P:他们是引用类型。它不会开始复制数据。请阅读我链接到的文章,其中有很多细节。但我期望文件的*结尾*被有效地切断,而不是开始。如果开始被切断,则表明在先前的读取操作中存在错误。 – 2010-09-20 21:46:41

3

为了增加乔恩斯基特的答案,你的阅读代码应是:

int bytesRead; 
int readPos = 0; 
do 
{ 
    bytesRead = currentStream.Read(fileSent, readPos, fileSent.Length); 
    readPos += bytesRead; 
} while (bytesRead > 0); 
+1

通过'do {...}直到(bytesRead == 0)'Jim表示'do {...} while(bytesRead> 0)'。除非有人在C#中添加do..until语句,当我不在寻找时。 – Tergiver 2010-09-20 20:52:42

+0

@Tergiver:谢谢。你是对的。我的帕斯卡尔正在展示(从我在帕斯卡尔写的东西开始已经有数年了)......我会解决的。 – 2010-09-20 22:20:57

0

如果您正在寻找在网络上发送和接收文件的通用解决方案你使用C# network library考虑?它可能已经解决了您在尝试执行此操作时遇到的大多数问题。

声明:我是该库的开发人员之一。