سؤال

أقوم بإنشاء تطبيق تنزيل وأرغب في تقويم الغرفة على Harddrive للملفات قبل تنزيلها فعليًا حيث يمكن أن تكون كبيرة إلى حد ما ، ولا يحب أي شخص أن يرى "محرك الأقراص ممتلئًا ، يرجى حذف بعض الملفات والمحاولة مرة أخرى. " لذلك ، في هذا الضوء ، كتبت هذا.

// Quick, and very dirty
System.IO.File.WriteAllBytes(filename, new byte[f.Length]);

إنه يعمل، على الأقل حتى تقوم بتنزيل ملف يصل حجمه إلى عدة مئات من الميغابايت، أو ربما حتى غيغابايت، وتقوم بإلقاء Windows في حالة جنون ساحق إذا لم تقم بمسح ملف ترحيل الصفحات بالكامل وقتل ذاكرة النظام لديك تمامًا.أُووبس.

لذلك، مع مزيد من التنوير، شرعت في استخدام الخوارزمية التالية.

using (FileStream outFile = System.IO.File.Create(filename))
{
    // 4194304 = 4MB; loops from 1 block in so that we leave the loop one 
    // block short
    byte[] buff = new byte[4194304];
    for (int i = buff.Length; i < f.Length; i += buff.Length)
    {
        outFile.Write(buff, 0, buff.Length);
    }
    outFile.Write(buff, 0, f.Length % buff.Length);
}

يعمل هذا جيدًا ولا يعاني من مشكلة الذاكرة المعطلة للحل الأخير.على الرغم من ذلك، فهو لا يزال بطيئًا، خاصة على الأجهزة القديمة لأنه يكتب بيانات (يحتمل أن تبلغ قيمتها جيجابايت) على القرص.

السؤال هو هذا:هل هناك طريقة أفضل لإنجاز نفس الشيء؟هل هناك طريقة لإخبار Windows بإنشاء ملف بحجم x وتخصيص المساحة على نظام الملفات بدلاً من كتابة كمية كبيرة من البيانات فعليًا.لا أهتم بتهيئة البيانات الموجودة في الملف على الإطلاق (البروتوكول الذي أستخدمه - bittorrent - يوفر تجزئات للملفات التي يرسلها، وبالتالي فإن أسوأ حالة للبيانات العشوائية غير المهيأة هي أنني أحصل على صدفة محظوظة وجزء من الملف صحيح).

هل كانت مفيدة؟

المحلول

FileStream.SetLength هو الذي تريده.بناء الجملة:

public override void SetLength(
    long value
)

نصائح أخرى

إذا كان عليك إنشاء الملف، أعتقد أنه يمكنك القيام بشيء مثل هذا:

using (FileStream outFile = System.IO.File.Create(filename))
{
    outFile.Seek(<length_to_write>-1, SeekOrigin.Begin);
    OutFile.WriteByte(0);
}

حيث length_to_write سيكون الحجم بالبايت للملف المراد كتابته.لست متأكدًا من صحة بناء جملة C# (ليس على جهاز كمبيوتر للاختبار)، لكنني قمت بأشياء مماثلة في C++ في الماضي وقد نجح الأمر.

لسوء الحظ، لا يمكنك فعل ذلك بمجرد السعي إلى النهاية.سيؤدي ذلك إلى تعيين طول الملف إلى شيء ضخم، لكنه قد لا يقوم فعليًا بتخصيص كتل القرص للتخزين.لذلك عندما تذهب لكتابة الملف، فإنه سيظل فاشلاً.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top