【问题标题】:Transfering a File with a NetworkStream then rebuilding the file fails使用 NetworkStream 传输文件然后重建文件失败
【发布时间】:2010-09-20 15:51:13
【问题描述】:

我正在尝试通过 NetworkStream 发送文件并在客户端重建它。我可以正确地获取数据(我认为),但是当我使用 BinaryWriter 或 FileStream 对象重新创建文件时,无论我使用什么方法,文件都会在同一点开始被切断。

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

    }

当我逐步检查文件名和文件大小时,它们是正确的。 byte[] 也被完全填充。关于下一步我可以做什么的任何线索?

提前谢谢...

肖恩

编辑!!!:

所以我弄清楚发生了什么。当我读取一个字符串然后从流中读取 Int 时,字节数组的长度为 256 个索引。所以我对字符串的读取正在接受 int,然后它将破坏其他区域。需要解决这个问题...

【问题讨论】:

  • 如果您需要进一步的帮助,您需要发布您的 ReadStringFromServer 和 ReadIntFromServer 方法。

标签: c# .net tcpclient networkstream


【解决方案1】:

一方面,您可以使用方便的方法File.WriteAllBytes 更简单地写入数据。但我怀疑这就是问题所在。

您假设您可以在一次 Read 调用中读取所有数据。您忽略了返回值。不要那样做 - 相反,阅读多次,直到你读完所有你期望的东西,或者你已经到达了流的末尾。见this article for more details。如果您使用的是 .NET 4,则有一个新的 CopyTo 方法可能对您有用。

(顺便说一句,您对ref 的使用表明您不理解它的真正含义。确保您理解how arguments are passed in C# 非常值得。)

【讨论】:

  • 这能解释为什么文件的开头被切断了吗?
  • 也没有传递网络流和连接以正确使用它,因为我不希望进行“复制”并且我对对象采取的所有操作都将全局反映?
  • @Sean P:它们是引用类型。它不会开始复制数据。请阅读我链接到的文章,其中包含很多细节。但我希望文件的 end 被有效地切断,而不是开始。如果开始被切断,则表明之前的读取操作有问题。
【解决方案2】:

要添加到 Jon Skeet 的答案,您的阅读代码应该是:

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

【讨论】:

  • do { ... } until (bytesRead == 0) Jim 的意思是 do { ... } while (bytesRead > 0)。除非有人在我不看的时候在 C# 中添加了 do..until 语句。
  • @Tergiver:谢谢。你是对的。我的 Pascal 正在显示(我已经有好几年没有用 Pascal 写过任何东西了)......我会修复的。
【解决方案3】:

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

免责声明:我是这个库的开发者之一。

【讨论】:

    猜你喜欢
    • 2011-04-09
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 2017-11-22
    • 1970-01-01
    相关资源
    最近更新 更多