2016-08-24 82 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

相關問題