2016-08-24 81 views
0

我目前正在编写客户端/服务器应用程序,需要将文件(音乐,视频,文本和其他类型)从服务器发送到客户端。目前,我写了以下两个功能:通过二进制序列化/反序列化通过TCP发送文件

let sendFile (client:TcpClient) (srcFilePath:string) = 
    let formatter = new BinaryFormatter() 

    // Deserialize message content to obj 
    use mStream = new MemoryStream() 
    ( 
     use fStream = File.OpenRead srcFilePath 
     fStream.CopyTo mStream 
    ) 
    let deserializedContent = formatter.Deserialize mStream 

    // Create and serialize message into network stream 
    let message = { Type = FileSync; Content = Some deserializedContent } 
    formatter.Serialize (client.GetStream(), message) 

该文件发送到客户端,并且在客户端接受它:

let readStreamToFile (client:TcpClient) outputPath = 
    let formatter = new BinaryFormatter() 

    try 
     let message = (formatter.Deserialize (client.GetStream())) :?> Message 
     match message.Type with 
     | FileSync -> 
      use fileStream = File.Open(outputPath, FileMode.Create) 
      match message.Content with 
      | Some content -> 
       formatter.Serialize (fileStream, message.Content) 
      | None -> 
       failwith "There was no content in the FileSync message!!!" 
     | _ -> 
      () 
    with 
    | :? InvalidCastException as ex -> 
     failwith "Message format unknown!!!" 

调用formatter.Deserialize mStream当我收到以下异常:

System.Runtime.Serialization.SerializationException:解析完成前遇到的流结束。

如果我绕过复制FileStreamMemoryStream,并调用formatter.Deserialize fStream相反,我收到以下异常在同一位置:

System.Runtime.Serialization.SerializationException:输入流不是有效的二进制格式。起始内容(以字节为单位)是:字节

为什么我BinaryFormatter无法反序列化我的文件内容?

编辑:

为了确保我流包含字节,我也曾尝试以下,但我收到同样的The input stream is not a valid binary format例外:

// Deserialize message content to obj 
let fileBytes = File.ReadAllBytes srcFilePath 
use mStream = new MemoryStream() 
mStream.Write (fileBytes, 0, fileBytes.Length) 
mStream.Position <- (int64)0 
let deserializedContent = formatter.Deserialize mStream 
+0

你调用'formatter.Deserialize mStream'发生在'use'作用域之后,所以当时'mStream'将被丢弃。我想知道为什么你没有得到'ObjectDisposedException' ... –

+0

这可能是我写的有点不清楚,但它实际上是文件流得到处置,只在括号之间使用。 – Choub890

回答

1

如果源文件是音乐,视频,那么他们的内容不会被.NET序列化。因此,反序列化它们将不起作用,这就是抛出异常的原因。你应该只读取这些文件,因为它们是无解串:

let sendFile (client:TcpClient) (srcFilePath:string) = 
    let formatter = new BinaryFormatter() 

    let fileContent = File.ReadAllBytes srcFilePath 

    // Create and serialize message into network stream 
    let message = { Type = FileSync; Content = Some fileContent } 
    formatter.Serialize (client.GetStream(), message) 

与此相一致,你不应该序列化在客户端的文件内容:

let readStreamToFile (client:TcpClient) outputPath = 
    let formatter = new BinaryFormatter() 

    try 
     let message = (formatter.Deserialize (client.GetStream())) :?> Message 
     match message.Type with 
     | FileSync -> 
      match message.Content with 
      | Some content -> 
       File.WriteAllBytes(outputPath, content) 
      | None -> 
       failwith "There was no content in the FileSync message!!!" 
     | _ -> 
      () 
    with 
    | :? InvalidCastException as ex -> 
     failwith "Message format unknown!!!" 

请注意,我已经改变了类型的内容从obj optionbyte[] option

相关问题