C ++ 17 ile bayt cinsinden dosya boyutu nasıl alınır


98

Bilmem gereken belirli işletim sistemleri için tuzaklar var mı?

Bu sorunun birçok kopyası ( 1 , 2 , 3 , 4 , 5 ) var ama onlarca yıl önce cevaplandı. Bugün bu soruların çoğunda çok yüksek oy alan cevaplar yanlış.

.Sx üzerindeki diğer (eski QA) yöntemleri

  • stat.h (sarmalayıcı sprintstatf ), sistem çağrısı kullanır

  • tellg () , tanım başına bir konum döndürür, ancak bayt olması gerekmez . Dönüş türü değildir int.



5
@LF: İlk soru ikincinin bir kopyası olarak kapatıldı, bu da birinci soruda kabul edilen cevabın neden yanlış olduğunu açıklıyor . Üçüncüsü, benzer tellgsorunları sormaktır. Rahatsız edilmeye değer tek kişi dördüncüsü ve bu ofstreamsoruda ve yanıtlarında çok fazla konuştuğu için harika değil . Bu, niyeti ifade etmede diğerlerinden çok daha iyidir (tuhaf bir şekilde kapatılan birincisi hariç).
Nicol Bolas

6
Lütfen sorunuza ve soru başlığına alakasız bilgiler eklemeyi bırakın. Yıl önemsizdir; teknolojiler önemlidir.
elixenide

2
Her stat(2)neyse nesi var ? Çok mu büyüdü ya da ne oldu?
Lorinczy Zsigmond

1
@LorinczyZsigmond Sorun nedir?stat(2) Dil standardının bir parçası değil.
Andrew Henle

Yanıtlar:


124

<filesystem>(C ++ 17'de eklenmiştir) bunu çok basit hale getirir .

#include <cstdint>
#include <filesystem>

// ...

std::uintmax_t size = std::filesystem::file_size("c:\\foo\\bar.txt");

Yorumlarda belirtildiği gibi, bu işlevi dosyadan kaç bayt okuyacağınıza karar vermek için kullanmayı planlıyorsanız, şunu unutmayın ...

... dosya sizin tarafınızdan özel olarak açılmadıkça, boyutu istediğiniz zaman ile ondan veri okumaya çalıştığınız zaman arasında değiştirilebilir.
- Nicol Bolas


11
Biraz konu dışı: Daha std::uintmax_tbüyük değerlere sahip olabileceği bir dünya var std::size_tmı? Değilse, neden kullanılmasın ki std::size_t, hangisi daha çok tanınır?
Cevapta

13
@Fureeish Sadece tür file_sizedöndüğü için kullandım. Bana da biraz tuhaf görünüyor.
HolyBlackCat

39
@Fureeish std::size_tyalnızca bellek nesnelerinin maksimum boyutunu tutması için gereklidir. Dosyalar önemli ölçüde daha büyük olabilir,
Richard Critten

27
@Fureeish 32 bit Windows'ta (ve çoğu modern 32 bit platformda varsayıyorum) size_t32 bit ve uintmax_t64 bittir.
HolyBlackCat

16
@HolyBlackCat: Dosya sisteminin global olduğu gerçeği hakkında bir şeyler söylemek iyi olur ve bu nedenle, dosya sizin tarafınızdan özel olarak açılmadıkça, boyutu istediğiniz zaman ile verileri okumaya çalıştığınız zaman arasında değiştirilebilir. ondan.
Nicol Bolas

28

C ++ 17 std::filesystem, dosyalar ve dizinler üzerinde birçok görevi kolaylaştıran bir özelliktir. Sadece dosya boyutunu ve özniteliklerini hızlı bir şekilde almakla kalmaz, aynı zamanda yeni dizinler oluşturabilir, dosyalar arasında yineleme yapabilir, yol nesneleriyle çalışabilirsiniz.

Yeni kütüphane bize kullanabileceğimiz iki işlev veriyor:

std::uintmax_t std::filesystem::file_size( const std::filesystem::path& p );

std::uintmax_t std::filesystem::directory_entry::file_size() const;

İlk işlev serbest bir işlev std::filesystem, ikincisi ise bir yöntemdir directory_entry.

Her yöntemin ayrıca bir istisna atabileceği veya bir hata kodu (bir çıkış parametresi aracılığıyla) döndürebileceği için bir aşırı yükü vardır. Aşağıda, tüm olası durumları açıklayan ayrıntı kodu verilmiştir.

#include <chrono>
#include <filesystem>  
#include <iostream>

namespace fs = std::filesystem;

int main(int argc, char* argv[])
{
    try
    {
        const auto fsize = fs::file_size("a.out");
        std::cout << fsize << '\n';
    }
    catch (const fs::filesystem_error& err)
    {
        std::cerr << "filesystem error! " << err.what() << '\n';
        if (!err.path1().empty())
            std::cerr << "path1: " << err.path1().string() << '\n';
        if (!err.path2().empty())
            std::cerr << "path2: " << err.path2().string() << '\n';
    }
    catch (const std::exception& ex)
    {
        std::cerr << "general exception: " << ex.what() << '\n';
    }

    // using error_code
    std::error_code ec{};
    auto size = std::filesystem::file_size("a.out", ec);
    if (ec == std::error_code{})
        std::cout << "size: " << size << '\n';
    else
        std::cout << "error when accessing test file, size is: " 
              << size << " message: " << ec.message() << '\n';
}

2
Bu tam olarak nedir"? Tüm bu kodun ne için kullanıldığını açıklayabilir misiniz, özellikle de kabul edilen cevap çok daha az kod kullandığında?
Nico Haase
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.