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


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.