无法将流复制到文件

时间:2012-12-28 07:12:31

标签: c# file-io windows-8 microsoft-metro windows-runtime

我必须从SpeechSynthesizer生成的流中创建一个音频文件。

这是使用

的代码
var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language);
            var reader = new Windows.Storage.Streams.DataReader(stream.GetInputStreamAt(0));
            await reader.LoadAsync((uint)stream.Size);

            byte[] bytes = new byte[stream.Size];
            reader.ReadBytes(bytes);

             var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting);

             using (var outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite))
             {

                 Stream os = outputStream.GetOutputStreamAt(0).AsStreamForWrite();
                 await os.WriteAsync(bytes, 0, bytes.Length);
             }

我发现问题是“os.WriteAsync”没有被等待。当我在该行放置断点并等待几秒钟时,文件正在正确创建。不应该等待关键字等到所有字节都被复制到流中,然后再转到下一行吗?

我不介意是否有人可以建议将InMemoryRandomAccessStream复制到文件的更好方法?

编辑:

Mahantesh的回答就像一个魅力。非常感谢。但我正面临一个新问题。

创建文件后我试图再次打开它来播放它但是收到了这个错误。

“访问被拒绝。(HRESULT异常:0x80070005(E_ACCESSDENIED))”

这是我的代码。

if (!cacheHit)
        {
            var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language);

            //write the stream to disk (seems to be buggy when attempting to playback from the result of the speech synth request)
            var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting);

             outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite);

             await RandomAccessStream.CopyAsync(stream, outputStream);                 

        }

        //read agenda from disk and play back the audio
        var agendaStorageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(_AgendaAudioFilename);
        var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read);            

        _MediaPlayer.Url = text;
        _MediaPlayer.SetBytestream(agendaStreamFromDisk);
        _MediaPlayer.Play();    

我在这一行收到错误:

var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read);

知道可能出现什么问题吗?

2 个答案:

答案 0 :(得分:1)

我认为你可以试试

await RandomAccessStream.CopyAsync(inMemoryStream, outputStream);

解决新问题:

if (!cacheHit)
    {
        var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language);

        //write the stream to disk (seems to be buggy when attempting to playback from the result of the speech synth request)
        var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting);

         using(outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite)){
         await RandomAccessStream.CopyAsync(stream, outputStream);}

    }

    //read agenda from disk and play back the audio
    var agendaStorageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(_AgendaAudioFilename);
   using (var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read)){

    _MediaPlayer.Url = text;
    _MediaPlayer.SetBytestream(agendaStreamFromDisk);
    _MediaPlayer.Play();  }

答案 1 :(得分:0)

当您使用await关键字进行等待时,最好使用同步版本的方法,例如

using (var outputStream = audioFile.Open(FileAccessMode.ReadWrite))
{
    Stream os = outputStream.GetOutputStreamAt(0).AsStreamForWrite();
    os.Write(bytes, 0, bytes.Length);
}