اوامر - ملفات سلسلات ثنائية سريعة وبسيطة في Powershell




اوامر powershell (3)

ما هي أفضل طريقة لسَلسَلة الملفات الثنائية باستخدام Powershell؟ أفضِّل استخدام مُحدد واحد سهل التذكر وسريع التنفيذ.

أفضل ما جئت به هو:

gc -Encoding Byte -Path ".\File1.bin",".\File2.bin" | sc -Encoding Byte new.bin

يبدو أن هذا يعمل جيدًا ، ولكنه بطيء جدًا مع الملفات الكبيرة.


الطريقة التي تتخذها هي الطريقة التي سأقوم بها في PowerShell. ومع ذلك يجب عليك استخدام -ReadCount المعلمة لتحسين الأداء. يمكنك أيضًا الاستفادة من المعلمات الموضعية لتقصير ذلك أكثر:

gc File1.bin,File2.bin -Enc Byte -Read 512 | sc new.bin -Enc Byte

فيما يتعلق باستخدام -ReadCount المعلمة ، قمت بنشر مدونة على هذا منذ فترة أن الناس قد تجد مفيدة - تحسين الأداء للحصول على محتوى لملفات كبيرة .


انها ليست Powershell ، ولكن إذا كان لديك Powershell لديك أيضا موجه الأوامر:

copy /b 1.bin+2.bin 3.bin

كما أشار كيث هيل ، إذا كنت بحاجة إلى تشغيله من داخل Powershell ، فيمكنك استخدام:

cmd /c copy /b 1.bin+2.bin 3.bin 

يعتمد الأداء بشكل كبير على حجم المخزن المؤقت المستخدم. تلك صغيرة إلى حد ما افتراضيا. تجميع ملفات 2x2GB كنت آخذ مخزونات من حوالي 256 كيلو بايت. قد يفشل الذهاب أكبر في بعض الأحيان ، أصغر وستحصل على معدل نقل أقل من محرك الأقراص الخاص بك قادر على.

باستخدام gc الذي سيكون مع -ReadCount ليس ببساطة -ReadCount (PowerShell 5.0):

gc -ReadCount 256KB -Path $infile -Encoding Byte | ...

بالإضافة إلى أنني وجدت Add-Content أن يكون أفضل وأن أذهب ملفًا لملفًا صغيرًا لكثير من الملفات الصغيرة ، نظرًا لأن أنبوبًا يحتوي على كمية معتدلة فقط من البيانات (200 ميجابايت) ، وجدت أن جهاز الكمبيوتر الخاص بي قد بدأ في العمل ، وتجميد PowerShell ووحدة المعالجة المركزية بالكامل.

على الرغم من أن " Add-Content يفشل عشوائياً عدة مرات لبضع مئات من الملفات مع وجود خطأ حول ملف الوجهة قيد الاستخدام ، لذلك أضفت حلقة أثناء وأمسك محاولة:

# Empty the file first
sc -Path "$path\video.ts" -Value @() -Encoding Byte 
$tsfiles | foreach {    
    while ($true) {
        try { # I had -ReadCount 0 because the files are smaller than 256KB
            gc -ReadCount 0 -Path "$path\$_" -Encoding Byte | `
                Add-Content -Path "$path\video.ts" -Encoding Byte -ErrorAction Stop
            break;
        } catch {
        }
    }
}

استخدام دفق ملف أسرع بكثير. لا يمكنك تحديد حجم المخزن المؤقت مع [System.IO.File]::Open ولكن يمكنك باستخدام new [System.IO.FileStream] مثل:

# $path = "C:\"
$ins = @("a.ts", "b.ts")
$outfile = "$path\out.mp4"
$out = New-Object -TypeName "System.IO.FileStream" -ArgumentList @(
    $outfile, 
    [System.IO.FileMode]::Create,
    [System.IO.FileAccess]::Write,
    [System.IO.FileShare]::None,
    256KB,
    [System.IO.FileOptions]::None)
try {
    foreach ($in in $ins) {
        $fs = New-Object -TypeName "System.IO.FileStream" -ArgumentList @(
            "$path\$in", 
            [System.IO.FileMode]::Open,
            [System.IO.FileAccess]::Read,
            [System.IO.FileShare]::Read,
            256KB,
            [System.IO.FileOptions]::SequentialScan)
        try {
            $fs.CopyTo($out)
        } finally {
            $fs.Dispose()
        }
    }
} finally {
    $out.Dispose()
}




powershell