在物理文件流中创建波文件有效,在内存流中创建失败,波头损坏

问题描述

我有一个带有 Wav-samples 的缓冲区,我想播放它。 使用 FileStream 这有效。 使用 MemoryStream 时它会失败,并在 soundplayer.Play 语句中出现 system.invalidOperationException 'The wave header iscorruption'。

这是有效的来源:

 Friend Sub New(buffer() As Byte,nBytes As Integer)
    'Dim wavStream As MemoryStream = New MemoryStream(CInt(nBytes + 44))
    Dim wavStream As FileStream = New FileStream("xxf.wav",FileMode.OpenorCreate)
    waveFormat = New WaveFormat(44100,16,2)
    Wwriter = New WaveWriter(wavStream,waveFormat)
    Wwriter.Write(buffer,nBytes)
    CType(Wwriter,Idisposable).dispose()
    'soundplayer = New System.Media.soundplayer(wavStream)
    soundplayer = New System.Media.soundplayer("xxf.wav")
    soundplayer.Play()
    soundplayer.dispose()
    soundplayer = nothing
    wavStream.dispose()
    wavStream.Close()
End Sub

更改 2 条注释行,以使用 MemoryStream 而不是 FileStream,我收到“波头已损坏”错误。 我用 C# 重写了源代码,结果相同。 我在 3 个地方查看了流缓冲区的内容。写入Wavheader后,写入数据后,处理后。由此产生的差异仅在块大小上:

after write of wavhdr:
 filestream   buffer(4) 12 127 26 0  (= 818970,the correct number of short samples)
 memorystream buffer(4) 36 0 0 0     (the number is there because I overwrite the same filedata)

after write of buffer:
 filestream   buffer(4) 12 127 26 0
 memorystream buffer(4) 36 0 0 0

after dispose: 
 identical  buffer(4) 12 127 26 0

我得出结论,流是由程序正确写入的,但没有(还?)由操作系统写入内存。但是我找不到可以添加的任何 dispose 或 Close 语句。 Wwriter 本身没有处置,但如果我不使用 Idisposable 处置文件,则 FileStream 版本不会失败,但也不会播放任何内容。 WavStream 只能在播放后关闭,因为流将被丢弃。 你明白我的错误是什么吗?

解决方法

正如两条评论中所写,问题在于在写入 MemoryStream 之后读取它。 写入过程没有关闭和处理数据的过程没有打开只能通过更改文件的位置来克服。 当使用 MemoryStream 时,这需要始终完成。会写,会读,中间数据中的指针需要重置为0。