如何避免StorageFile.CopyAsync()在复制大文件时抛出异常?

时间:2014-05-26 08:54:22

标签: windows-phone-8.1

我要通过StorageFile.CopyAsync()方法将某些文件从视频库复制到我的应用存储空间,但如果文件的大小超过1GB,则会抛出异常,如下所示:

  

类型:System.Runtime.InteropServices.COMException消息:错误   HRESULT E_FAIL已从调用COM组件返回。   Stacktrace:at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()

如何导入大文件,是否有解决此问题的解决方案?

2 个答案:

答案 0 :(得分:5)

我会尝试通过缓冲区复制它 - 例如:

private async Task CopyBigFile(StorageFile fileSource, StorageFile fileDest, CancellationToken ct)
{
   using (Stream streamSource = await fileSource.OpenStreamForReadAsync())
   using (Stream streamDest = await fileDest.OpenStreamForWriteAsync())
       await streamSource.CopyToAsync(streamDest, 1024, ct);
   return;
}

答案 1 :(得分:1)

我写了一个扩展方法,它解决了我的问题,你可以在需要时参考它,如下:

public static class FileExtentions
{
    #region Fields
    private static readonly ulong MaxBufferSize = 16 * 1024 * 1024;
    #endregion // Fields

    #region Methods
    public static async Task<StorageFile> CopyAsync(this StorageFile self, StorageFolder desiredFolder, string desiredNewName, CreationCollisionOption option)
    {
        StorageFile desiredFile = await desiredFolder.CreateFileAsync(desiredNewName, option);
        StorageStreamTransaction desiredTransaction = await desiredFile.OpenTransactedWriteAsync();
        BasicProperties props = await self.GetBasicPropertiesAsync();
        IInputStream stream = await self.OpenSequentialReadAsync();

        ulong copiedSize = 0L;
        while (copiedSize < props.Size)
        {
            ulong bufferSize = (props.Size - copiedSize) >= MaxBufferSize ? MaxBufferSize : props.Size - copiedSize;
            IBuffer buffer = BytesToBuffer(new byte[bufferSize]);
            await stream.ReadAsync(buffer, (uint)bufferSize, InputStreamOptions.None);
            await desiredTransaction.Stream.GetOutputStreamAt(copiedSize).WriteAsync(buffer);
            buffer = null;
            copiedSize += (bufferSize);

            Debug.WriteLine(DeviceStatus.ApplicationCurrentMemoryUsage);
        }

        await desiredTransaction.CommitAsync();

        return desiredFile;
    }

    private static IBuffer BytesToBuffer(byte[] bytes)
    {
        using (var dataWriter = new DataWriter())
        {
            dataWriter.WriteBytes(bytes);
            return dataWriter.DetachBuffer();
        }
    }
    #endregion // Methods