6

最近、からに変更する必要があり、使用方法File.Copy()CopyFileEx見つけるのに苦労しています。

たくさんグーグルした後、私はそれを使用するためのこの素晴らしいラッパーを見つけました、しかし私が必要とするのは現在のファイルのコピーされたバイトの進行状況を取得し、可能であれば私がそれに渡すすべてのファイルのコピーの進行状況を計算することです。

(プログレスバーがリンクされているプロジェクトがあることは知っていますがCopyFileEx、関連するコードを引き出すのに十分な経験がないので、このラッパーを使用したいと思います)。

おそらく、それをコピーするファイルの合計バイト数と比較し、それからパーセンテージを計算するだけです。

私の現在のコピー方法は

FileRoutines.CopyFile(new FileInfo("source.txt"), new FileInfo("dest.txt"));

私が立ち往生しているのは、進行状況情報を取得するために必要なパラメーターでオーバーロードする方法です。

public sealed class FileRoutines
{
    public static void CopyFile(FileInfo source, FileInfo destination)
    {
        CopyFile(source, destination, CopyFileOptions.None);
    }

    public static void CopyFile(FileInfo source, FileInfo destination, 
        CopyFileOptions options)
    {
        CopyFile(source, destination, options, null);
    }

    public static void CopyFile(FileInfo source, FileInfo destination, 
        CopyFileOptions options, CopyFileCallback callback)
    {
        CopyFile(source, destination, options, callback, null);
    }

    public static void CopyFile(FileInfo source, FileInfo destination, 
        CopyFileOptions options, CopyFileCallback callback, object state)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (destination == null) 
            throw new ArgumentNullException("destination");
        if ((options & ~CopyFileOptions.All) != 0) 
            throw new ArgumentOutOfRangeException("options");

        new FileIOPermission(
            FileIOPermissionAccess.Read, source.FullName).Demand();
        new FileIOPermission(
            FileIOPermissionAccess.Write, destination.FullName).Demand();

        CopyProgressRoutine cpr = callback == null ? 
            null : new CopyProgressRoutine(new CopyProgressData(
                source, destination, callback, state).CallbackHandler);

        bool cancel = false;
        if (!CopyFileEx(source.FullName, destination.FullName, cpr, 
            IntPtr.Zero, ref cancel, (int)options))
        {
            throw new IOException(new Win32Exception().Message);
        }
    }

    private class CopyProgressData
    {
        private FileInfo _source = null;
        private FileInfo _destination = null;
        private CopyFileCallback _callback = null;
        private object _state = null;

        public CopyProgressData(FileInfo source, FileInfo destination, 
            CopyFileCallback callback, object state)
        {
            _source = source; 
            _destination = destination;
            _callback = callback;
            _state = state;
        }

        public int CallbackHandler(
            long totalFileSize, long totalBytesTransferred, 
            long streamSize, long streamBytesTransferred, 
            int streamNumber, int callbackReason,
            IntPtr sourceFile, IntPtr destinationFile, IntPtr data)
        {
            return (int)_callback(_source, _destination, _state, 
                totalFileSize, totalBytesTransferred);
        }
    }

    private delegate int CopyProgressRoutine(
        long totalFileSize, long TotalBytesTransferred, long streamSize, 
        long streamBytesTransferred, int streamNumber, int callbackReason,
        IntPtr sourceFile, IntPtr destinationFile, IntPtr data);

    [SuppressUnmanagedCodeSecurity]
    [DllImport("Kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    private static extern bool CopyFileEx(
        string lpExistingFileName, string lpNewFileName,
        CopyProgressRoutine lpProgressRoutine,
        IntPtr lpData, ref bool pbCancel, int dwCopyFlags);
}

public delegate CopyFileCallbackAction CopyFileCallback(
    FileInfo source, FileInfo destination, object state, 
    long totalFileSize, long totalBytesTransferred);

public enum CopyFileCallbackAction
{
    Continue = 0,
    Cancel = 1,
    Stop = 2,
    Quiet = 3
}

[Flags]
public enum CopyFileOptions
{
    None = 0x0,
    FailIfDestinationExists = 0x1,
    Restartable = 0x2,
    AllowDecryptedDestination = 0x8,
    All = FailIfDestinationExists | Restartable | AllowDecryptedDestination
}

どんなポインタも本当にありがたいです。

4

2 に答える 2

8

ラッパーには、進行状況を処理するために必要な配管がすでにあります。戻る前に、CallbackHandlerのプログレスバーを更新するコードを実装するだけです。progressBar1.Maximumのデフォルトは100であるため、以下のコードでパーセンテージが計算されます。

現在のCopyFile呼び出しを次のように置き換えます。

CopyFileCallbackAction myCallback(FileInfo source, FileInfo destination, object state, long totalFileSize, long totalBytesTransferred)
{
    double dProgress = (totalBytesTransferred / (double)totalFileSize) * 100.0;
    progressBar1.Value = (int)dProgress;
    return CopyFileCallbackAction.Continue;
}

FileRoutines.CopyFile(new FileInfo("source.txt"), new FileInfo("dest.txt"), myCallback);
于 2012-12-20T16:26:27.700 に答える
0

ファイルコピーの進行状況バーを表示したいだけの場合は、これを行うことができます。プログレスバーと残り時間を表示するWindows標準ダイアログを使用し、[キャンセル]ボタンがあります。基本的に1行のコードで必要なものでした。

// The following using directive requires a project reference to Microsoft.VisualBasic. 
using Microsoft.VisualBasic.FileIO;

class FileProgress
{
    static void Main()
    {
        // Specify the path to a folder that you want to copy. If the folder is small,  
        // you won't have time to see the progress dialog box. 
        string sourcePath = @"C:\Windows\symbols\";
        // Choose a destination for the copied files. 
        string destinationPath = @"C:\TestFolder";

        FileSystem.CopyDirectory(sourcePath, destinationPath,
            UIOption.AllDialogs);
    }
}
于 2016-09-01T14:45:19.690 に答える