ডিস্কে ফাইলের আকার পান


85
var length = new System.IO.FileInfo(path).Length;

এটি ডিস্কের আকারের পরিবর্তে ফাইলটির লজিক্যাল আকার দেয়।

আমি উইন্ডোজ এক্সপ্লোরার দ্বারা রিপোর্ট করা হিসাবে সি # তে (সাধারণত ইন্টারপ ছাড়াই ) ডিস্কের কোনও ফাইলের আকার পেতে চাই ।

এটি সহ সঠিক আকার দেওয়া উচিত:

  • একটি সংকুচিত ফাইল
  • একটি বিরল ফাইল
  • একটি খণ্ডিত ফাইল

উত্তর:


50

এটি হ'ল প্রস্তাবিত হিসাবে গেটকম্প্রেসড ফাইলসাইজ এবং গেটডিস্কফ্রিস্পেস ব্যবহার করে, যেমন পলস্ট্যাক পরামর্শ দিয়েছে, তবে এটি পি / ইনভোক ব্যবহার করে। আমি এটি কেবল সংক্ষেপিত ফাইলগুলির জন্য পরীক্ষা করেছি এবং আমার সন্দেহ হয় যে এটি খণ্ডিত ফাইলগুলির জন্য কাজ করে না।

public static long GetFileSizeOnDisk(string file)
{
    FileInfo info = new FileInfo(file);
    uint dummy, sectorsPerCluster, bytesPerSector;
    int result = GetDiskFreeSpaceW(info.Directory.Root.FullName, out sectorsPerCluster, out bytesPerSector, out dummy, out dummy);
    if (result == 0) throw new Win32Exception();
    uint clusterSize = sectorsPerCluster * bytesPerSector;
    uint hosize;
    uint losize = GetCompressedFileSizeW(file, out hosize);
    long size;
    size = (long)hosize << 32 | losize;
    return ((size + clusterSize - 1) / clusterSize) * clusterSize;
}

[DllImport("kernel32.dll")]
static extern uint GetCompressedFileSizeW([In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
   [Out, MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh);

[DllImport("kernel32.dll", SetLastError = true, PreserveSig = true)]
static extern int GetDiskFreeSpaceW([In, MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName,
   out uint lpSectorsPerCluster, out uint lpBytesPerSector, out uint lpNumberOfFreeClusters,
   out uint lpTotalNumberOfClusters);

আপনি কি নিশ্চিত যে এটি সঠিক কিনা (ফলাফল == 0) নতুন Win32Exception (ফলাফল) নিক্ষেপ করে;
সাইমন

' If (ফলাফল == 0)' বিটটি সঠিক ( এমএসডিএন দেখুন ), তবে আপনি ঠিক বলেছেন যে আমি ভুল নির্মাতা ব্যবহার করছি। আমি এখন এটি ঠিক করব।
margnus1

FileInfo.Directory.Rootদেখে মনে হচ্ছে না এটি কোনও ধরণের ফাইল সিস্টেম লিঙ্কগুলি পরিচালনা করতে পারে। সুতরাং এটি কেবল ক্লাসিক স্থানীয় ড্রাইভ অক্ষরে কোনও সিমলিংক / হার্ডলিঙ্ক / জংশন পয়েন্ট বা এনটিএফএসের যা অফার রয়েছে তা নিয়ে কাজ করে।
ygoe

কেউ দয়া করে ধাপে ধাপে ব্যাখ্যা দিতে পারেন, বিভিন্ন পদক্ষেপে কী করা হয়েছে? এটি আসলে কীভাবে কাজ করে তা বুঝতে খুব সহায়ক হবে han ধন্যবাদ।
বাপি

4
এই কোডটির নামস্থান System.ComponentModelএবং প্রয়োজন System.Runtime.InteropServices
কেনি ইভিট

17

উপরের কোডটি উইন্ডোজ সার্ভার 2008 বা 2008 আর 2 বা উইন্ডোজ 7 এবং উইন্ডোজ ভিস্তা ভিত্তিক সিস্টেমে যথাযথভাবে কাজ করে না কারণ ক্লাস্টারের আকার সর্বদা শূন্য থাকে ( ইউএসি অক্ষম থাকা সত্ত্বেও getDiskFreeSpaceW এবং getDiskFreeSpace রিটার্ন -1 ) এখানে কার্যকরভাবে পরিবর্তিত কোডটি কাজ করে।

সি #

public static long GetFileSizeOnDisk(string file)
{
    FileInfo info = new FileInfo(file);
    uint clusterSize;
    using(var searcher = new ManagementObjectSearcher("select BlockSize,NumberOfBlocks from Win32_Volume WHERE DriveLetter = '" + info.Directory.Root.FullName.TrimEnd('\\') + "'") {
        clusterSize = (uint)(((ManagementObject)(searcher.Get().First()))["BlockSize"]);
    }
    uint hosize;
    uint losize = GetCompressedFileSizeW(file, out hosize);
    long size;
    size = (long)hosize << 32 | losize;
    return ((size + clusterSize - 1) / clusterSize) * clusterSize;
}

[DllImport("kernel32.dll")]
static extern uint GetCompressedFileSizeW(
   [In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
   [Out, MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh);

ভিবি.এনইটি

  Private Function GetFileSizeOnDisk(file As String) As Decimal
        Dim info As New FileInfo(file)
        Dim blockSize As UInt64 = 0
        Dim clusterSize As UInteger
        Dim searcher As New ManagementObjectSearcher( _
          "select BlockSize,NumberOfBlocks from Win32_Volume WHERE DriveLetter = '" + _
          info.Directory.Root.FullName.TrimEnd("\") + _
          "'")

        For Each vi As ManagementObject In searcher.[Get]()
            blockSize = vi("BlockSize")
            Exit For
        Next
        searcher.Dispose()
        clusterSize = blockSize
        Dim hosize As UInteger
        Dim losize As UInteger = GetCompressedFileSizeW(file, hosize)
        Dim size As Long
        size = CLng(hosize) << 32 Or losize
        Dim bytes As Decimal = ((size + clusterSize - 1) / clusterSize) * clusterSize

        Return CDec(bytes) / 1024
    End Function

    <DllImport("kernel32.dll")> _
    Private Shared Function GetCompressedFileSizeW( _
        <[In](), MarshalAs(UnmanagedType.LPWStr)> lpFileName As String, _
        <Out(), MarshalAs(UnmanagedType.U4)> lpFileSizeHigh As UInteger) _
        As UInteger
    End Function

System.Managment রেফারেন্সটি এই কোডটি কাজ করার জন্য প্রয়োজন। এটি প্রদর্শিত হবে যেন ডাব্লুএমআই ব্যতীত উইন্ডোজ (6.x সংস্করণ) এ ক্লাস্টারের আকার সঠিকভাবে পাওয়ার কোনও মানক উপায় নেই। : |
স্টিভ জনসন

4
আমি আমার কোডটি একটি ভিস্তার x64 মেশিনে লিখেছি এবং এখন এটি একটি ডাব্লু 7 এক্স 64 মেশিনে 64-বিট এবং ডাব্লুডাব্লু 64 মোডে পরীক্ষা করেছি। নোট করুন যে গেটডিস্কফ্রিস্পেস সাফল্যে ননজারো ফেরানোর কথা
margnus1

4
আসল প্রশ্নটি সি #
শেন কোর্ট্রিল

4
এই কোডটিও সংকলন করে না (একটি ক্লোজিং বন্ধনী ব্যবহারের অনুপস্থিত) এবং একটি লাইনার শেখার উদ্দেশ্যে খুব ভয়ঙ্কর
মিকেল ভি।

4
আপনি কোডটি প্রথম কলটি ব্যবহার করতে চাইলে এই কোডটি .First()একটি IEnumerableএবং একটি নয় হিসাবে অনুরোধ IEnumerable<T>করার সময় এই .Cast<object>()
কোডটিতে একটি সংকলন সমস্যাও রয়েছে

5

এমএসডিএন সামাজিক ফোরাম অনুসারে:

ডিস্কে থাকা আকারটি ফাইলটি সংরক্ষণ করে এমন ক্লাস্টারগুলির আকারের সমষ্টি হতে হবে: ক্লাস্টারের আকার খুঁজতে আপনাকে পি / ইনভোকের
long sizeondisk = clustersize * ((filelength + clustersize - 1) / clustersize);
মধ্যে ডুবতে হবে ; এটি ফেরত দেয়GetDiskFreeSpace()

সি # তে কোনও ফাইলের ডিস্কে আকার কীভাবে পাবেন তা দেখুন ।

তবে দয়া করে নোটটি নোট করুন যে এটি এনটিএফএসে কাজ করবে না যেখানে কম্প্রেশন চালু আছে is


4
আমি সংকুচিত এবং / বা স্পার্স ফাইলগুলির জন্য অ্যাকাউন্ট করার GetCompressedFileSizeচেয়ে কিছু জাতীয় ব্যবহার করার পরামর্শ দিই filelength
হ্যানস ওলসন

-1

আমি মনে করি এটি এমন হবে:

double ifileLength = (finfo.Length / 1048576); //return file size in MB ....

নিশ্চিতকরণ পেতে আমি এর জন্য এখনও কিছু পরীক্ষা নিরীক্ষা করছি।


7
এটি ফাইলের আকার (ফাইলের মধ্যে বাইট সংখ্যা)। প্রকৃত হার্ডওয়্যারটির ব্লক আকারের উপর নির্ভর করে কোনও ফাইল আরও বেশি ডিস্কের জায়গা ব্যবহার করতে পারে। যেমন আমার এইচডিডি-তে 600byte এর একটি ফাইল ডিস্কে 4kB ব্যবহার করে B সুতরাং এই উত্তরটি ভুল।
0xBADF00D
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.