我目前正在编写客户端/服务器应用程序,需要将文件(音乐,视频,文本和任何其他类型)从服务器发送到客户端。目前,我写了以下两个函数:
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:解析完成之前遇到的Stream of End。
如果我绕过将FileStream
复制到MemoryStream
,然后拨打formatter.Deserialize fStream
,我会在同一位置收到以下异常:
System.Runtime.Serialization.SerializationException:输入流不是有效的二进制格式。起始内容(以字节为单位)为: bytes
为什么我的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 :(得分: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 option
更改为byte[] option
。