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?
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;
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With