How to avoid StorageFile.CopyAsync() throw exception when copying big file?

元气小坏坏 提交于 2019-12-10 13:24:19

问题


I'm going to copy some files from Video Library to my app storage through StorageFile.CopyAsync() method, but if a file's size is more than 1GB, it would throw an exception as follow:

Type: System.Runtime.InteropServices.COMException Message: Error HRESULT E_FAIL has been returned from a call to a COM component. Stacktrace: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()

How can I import a big file, Is there have a solution to solve this problem?


回答1:


I would try to copy it via buffer - for example like this:

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;
}



回答2:


I write a extension method, it solved my problem, you can refer to it when you need as follows:

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


来源:https://stackoverflow.com/questions/23866325/how-to-avoid-storagefile-copyasync-throw-exception-when-copying-big-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!