如何在Windows 8或8.1上取消复制交易?

时间:2014-06-09 03:28:30

标签: windows-8

我正在尝试通过StorageFile.CopyAsync()复制文件,有时我需要在复制大文件时取消它,怎么办呢?

1 个答案:

答案 0 :(得分:0)

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

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

        try
        {
            ulong copiedSize = 0L;
            while (copiedSize < props.Size)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    break;
                }
                else
                {
                    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);
                    await desiredTransaction.Stream.GetOutputStreamAt(copiedSize).FlushAsync();
                    buffer = null;
                    copiedSize += (bufferSize);
                }
            }
        }
        catch (Exception exc)
        {
            Logger.Log.Warn(exc);
        }

        await desiredTransaction.CommitAsync();

        if (cancelToken.IsCancellationRequested)
        {
            await desiredFile.DeleteAsync();
        }

        return desiredFile;
    }

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