• ikili dosya. Özel veri türlerini ikili dosyalara yazma ve okuma

    Hakkında bazı makaleleri okurken muhtemelen "metin" ve "ikili" terimleriyle karşılaşmışsınızdır. Ve tüm bunların senin için çok zor olduğuna karar verdiler, bunu sonsuza kadar çözemezsin, bu yüzden derinlemesine araştırmadılar, ellerini ona salladılar.

    Her şeyi mümkün olduğunca açıklamaya çalışacağız. sade dil, çünkü bu tür bilgiler, bilgisayar güvenliğinin temelleriyle doğrudan ilgili oldukları için en deneyimsiz olanlar bile her kullanıcı için yararlıdır.

    biraz teori

    Metin dosyası ASCII karakterlerini içerir (kısaltma Amerikan Standart Kod bilgi için Değişim, "Bilgi Değişimi için Amerikan Standart Kodlaması" gibi bir şey).

    Aslında ASCII, her harf, sayı, noktalama işareti ve çeşitli "köpekler" ile "kar taneleri" (@ ve * anlamında) bir bayt tahsis edilen bir tablodur. Yani, her biri sekiz sıfır ve bir (bit). Artı, elbette, yeni satır gibi karakterleri kontrol edin.

    Bir ASCII dosya açıcı, baytları ekranda harflere, sayılara ve diğer yazdırılabilir karakterlere dönüştürür. Tabii ki yazılım, tablonun Rus diline karşılık gelen kısmını anlamalıdır, ancak bu zaten bir kodlama meselesidir.

    Bir ikili dosyada, sıfırlar ve birler, metinleri görüntülemek için gerekli olmayan dizilerde düzenlenir (bazıları olmasına rağmen, örneğin, *doc). Ve ne için soruyorsun. Cevap basit: diğer her şey. Programlar, filmler, müzik, resimler - her formatın verileri düzenlemek için kendi yapısal ilkeleri vardır.

    "İkili" kelimesinin kendisi "iki bileşenden oluşan", "çift" anlamına gelir. Aslında, yalnızca iki bileşen açıkça tanımlanabilir - dosyayı oluşturan sıfır ve bir, bitler, "tuğlalar". Diğer her şeyin anlamı yalnızca başlatma sırasında (açılış, oynatma) görünebilir.

    Dijital dünyanın alt tarafı

    İle ikili dosyanın içine bakabilirsiniz. özel program- HEX editörü. (Onaltılık sayı sistemini ifade eden Onaltılık kelimesinden.) Bu tür yazılımlar, baytları aslında bir tablo (matris) biçiminde düzenlenmiş olan HEX tanımlamaları biçiminde gösterir.

    Örneğin, görüntü baytları JPEG biçimi, normal bir resim veya fotoğraf, editör penceresinde FF D8 FF 00 04 3A 29 vb. olarak gösterilecektir.

    Uzman, en baştaki FF D8 bayt dizisinin önümüzde JPEG olduğunu gösterdiğini anlayacaktır. Ve uzman olmayanlar için o kadar da ilginç değil.

    HEX editöründe açabilir ve Metin dosyası hangi baytların belirli harflere (ASCII karakterleri) karşılık geldiğini görmek için. Ama sadece meraktan, hala bir anlam ifade etmiyor.

    Ancak ikili dosyalar, oldukça anlamlı ve belirli hedeflerle onaltılık biçimde görüntülenir. Örneğin, anti-virüs laboratuvarlarından uzmanlar, ana koda eklenen kötü amaçlı kodu bu şekilde arar. Bu arada güvenlik konularına geçelim.

    Ne zarar verebilir

    Bir metin dosyası, ASCII karakterlerinden başka bir şey içeremez. Ancak programlar sadece ikili değil, aynı zamanda yukarıdaki sembollerden oluşur. Senaryolardan bahsediyorum tabii ki.

    Başka bir deyişle, *txt dosyası prensipte virüslü değildir ve bir tehdit oluşturmaz. Ve metin dosyasının içinde bir komut dosyası varsa, o zaman çok fazla sorun yaratabilir.

    Örneğin, *bat dosyası çeşitli komutların kodunu içerir ve aşağıdaki gibi çift tıklanarak başlatılır: düzenli program. Bu komutlar ASCII karakterleriyle yazılmıştır, ancak işletim sistemi bunları yorumlayabilir - sıfırlara ve programlar için tipik olan birlere dönüştürebilir.

    Ama kesinlikle bilinmeyen yarasa dosyalarına tıklamıyorsun, değil mi? Bu iyi.

    Önceki yayınlar:

    Son düzenleme: 2012-11-06 14:45:16

    Malzeme etiketleri: ,

    İkili dosyalarla çalışma

    Tüm bilgiler bilgisayarda 0 ve 1 şeklinde, yani ikili biçimde saklanır. İkili dosyalar, metin dosyalarından yalnızca işlenme biçimleri bakımından farklılık gösterir. Örneğin, bir metin dosyasına "4" sayısını yazarsak, o zaman bir karakter olarak yazılır ve onu depolamak için bir bayt gerekir. Buna göre, dosya boyutu bir bayta eşit olacaktır. "145687" girişini içeren metin dosyasının boyutu altı bayt olacaktır.

    145687 tamsayısını bir ikili dosyaya yazarsak, o zaman dört bayt boyutunda olacaktır, çünkü bu, int türündeki verileri depolamak için gereken miktardır. Yani, ikili dosyalar daha derli topludur ve bazı durumlarda işlenmesi daha kolaydır.

    Standart Veri Türlerini İkili Dosyalara Yazma

    Bir ikili dosyayı açmak için, erişim kipini ios::binary olarak ayarlamanız gerekir (bazı C++ derleyicilerinde, ios::bin).

    Bir çıktı dosyası oluşturmak için bir nesne oluşturun:

    çıkış outBinFile("out.bin", ios::out | ios::binary);

    /* sınıf nesnesi oluşturma akış dışı dışarı. çöp Kutusu

    eğer (! out_f ve 1) // standart kontrol

    Veriler, iki parametreye sahip olan write () yöntemi kullanılarak yazılır: ilki, yazılan verilerin başlangıcına (başlangıç ​​adresi) bir işaretçidir, ikincisi, yazılacak bayt sayısıdır. Bu durumda, işaretçi açıkça char türüne dönüştürülmelidir.

    örnek 1Çeşitli türlerdeki değişkenleri bir ikili dosyaya yazın:

    çıkış outBinFile("test.bin", ios::out I

    ios: :ikili); /^sınıf nesnesi oluştur akış ve onu bir dosyaya bağlamaya çalışıyorumÖlçek. çöp Kutusu ikili yazma modunda */

    int - 145687; // bir tamsayı değişkeninin bildirimi A

    outBinFile. write ((char*) &a, sizeof(a)) ; /^ dosyaya yaz

    değişken A bir bayt akışı olarak, yani bir dosyaya bir tamsayı değişkeninin dahili gösterimini yazmak a */ kayan nokta x - 123,25; // gerçek değişken bildirimi X

    outBinFile .write ((char*) &x, sizeof(x)) ; /^ dosyaya yaz

    değişken X bir bayt akışı olarak, yani bir dosyaya x*/ tamsayı değişkeninin dahili temsilini yazmak

    //karakter değişken tanımıİle ve g ile başlatılıyor outBinFile.write((char*)&c, sizeof(c));

    //karakter girişi G dosyalamak

    outBinFile.close(); 0 dönüşü;

    Test .bin dosyasının içeriğini bir metin düzenleyiciyle açarsanız, şöyle görünecektir:

    ve dosya boyutu 9 bayt olacaktır.

    Standart veri türlerinin okunması ikili dosyalar

    Mevcut bir ikili dosyayı okumak üzere açmak için bir nesne oluşturmanız gerekir:

    ifstream inpBinFile("inp.bin", ios::in I ios::binary);

    /* dosyanın ikili biçimde okumak için açıldığını gösteren bir işaret ayrımı kullanın */

    if(!inpBinFile)

    cout Verileri okumak için, write() işlevine benzer parametrelere sahip read() işlevini kullanırız.

    #include ad alanı std'sini kullanarak; int ana()

    ifstream inpBinFile("test.bin", ios::in I

    ios: :ikili); / / dosyayı ikili biçimde okumak için aç

    int bir; yüzen x; karakter c = "g";

    inpBinFile.read((char*)'a, sizeof(a));

    // tamsayı değişkenini oku inpBinFile.read((char*)&x, sizeof(x));

    //gerçek değişkeni oku inpBinFile.read((char*)&c, sizeof(c));

    // karakter değişkenini oku

    inpBinFile.close(); cout

    Programın sonucu:

    a = 145687 x = 123,25 c = g

    Yazma ve okuma işlevlerini kullanırken hiçbir bilgi dönüştürmenin gerçekleşmediğini unutmayın. Verilerin dahili gösterimi dosyaya yazılır ve dosyadan okunur. Bu nedenle önceki iki program doğru sonucu verdi.

    Özel veri türlerini ikili dosyalara yazma ve okuma

    Metin dosyalarından farklı olarak, ikili dosyaları kullanarak özel veri türleriyle çalışmanın standart veri türlerinden hiçbir farkı yoktur. write() ve read() yöntemleri benzer şekilde kullanılır. Programcının, herhangi bir veri dönüştürmenin gerçekleşmediğini, yalnızca bilgilerin dahili temsilinin yazıldığını ve okunduğunu dikkate alarak, yalnızca yazılacak bellek alanının adresini ve yazılacak bayt sayısını belirtmesi gerekir.

    Ayrıca ikili dosyalarla çalışırken,seeng(), tellg(),seep(), tellp() yöntemleri kullanılabilir.

    Örnek 3 Bir grup turist hakkında bilgileri bir ikili dosyaya yazan bir program yazınız.

    fstream BinFile("ankety.bin", ios::in I ios::out | ios::binary);

    Anket Grubu = ; için (int ben = 0; ben

    BinFile.write((char*)&Gruppa[i], sizeof(Anketa)); BinFile.close(); 0 dönüşü;

    Örnek 4"Ankety.bin" dosyası bir grup turist hakkında veri içerir, bunları okumak ve ekranda görüntülemek gerekir.

    #include ad alanı std'sini kullanarak; yapı sorusu (

    karakter ismi; yaş;

    yapısal veri türü anket ekranda*/

    akış ve operatör

    fstream BinFile("ankety.bin", ios::in | ios::out | ios::binary); eğer (!BinFile)

    için (int ben = 0; ben

    //tür değişkeninin kapladığı tüm baytları hemen oku Anketa BinFile.read((char*)&Gruppa[i], sizeof(Anketa));

    BinFile.close(); 0 dönüşü;

    Programın sonucu:

    İvanov, 23 Sidorov, 21 Petrov,22

    Devam etmek için herhangi bir tuşa basın. . .

    Dosyalarla çalışmak için kendi sınıflarınızı geliştirme

    Sürekli write() ve read() metodlarını kullanmak sakıncalı, ">" işlemlerini text dosyalarına benzeterek kullanabilmek çok daha güzel. İkili dosyalarla çalışmak için sınıfımızın uygulanmasına bir örnek verelim.

    ad alanı std kullanarak;

    yapı sorusu //bilgi depolamak için bir yapı bildirmek

    /* özel bir çıktı almak için ekleme işlemini akışa aşırı yükleme

    yapısal veri türü anket ekranda*/

    akış ve operatör

    sınıf outBinaryFile: genel /^ akışının çıktı ikili dosyalarıyla çalışmak için sınıfımızı tanımlarız. Çıktı dosyası akışlarıyla çalışmak için sınıftan üretiyoruz */

    /* üretilen sınıfın yapıcısını tanımlarken, gerekli parametreleri ona ileterek temel sınıfın yapıcısını çağırmayı unutmayın */

    outBinaryFile(char* adı) : ofstream(ad, ios::out I ios::binary)

    //gerekli işlemleri sınıf yöntemleri olarak aşırı yükle outBinaryFile& operatörü

    write((char*)&chislo, sizeof(chislo)); *bunu geri ver;

    outBinaryFile& operatörü

    write((char*)&ank, sizeof(ank)); *bunu geri ver;

    inpBinaryFile sınıfı: akış /* ise genel sınıfımızı giriş ikili dosyalarıyla çalışacak şekilde tanımlarız. Girdi dosyası akışlarıyla çalışmak için sınıftan üretiyoruz */

    inpBinaryFile(char* adı) : ifstream(ad, ios::in I ios::binary)

    /*temel sınıf yapıcısını gerekli parametrelerle çağırın,

    türetilmiş sınıfın yapıcısı için yeterli */

    // gerekli işlemleri aşırı yükle

    inpBinaryFile& operatörü >> (int& sayı)

    read((char*)&chislo, sizeof(chislo)); *bunu geri ver;

    inpBinaryFile& operatörü >> (Anketa& ank)

    read((char*)&ank, sizeof(ank)); *bunu geri ver;

    int a = 111, b = 112; outBinaryFile outFile("dannye.bin");

    // dosyayı okumak için aç

    inpBinaryFile inpFile("dannye.bin"); eğer (!inpDosyası)

    için (int ben = 0; ben

    inpFile >> a; //anketi dosyadan oku

    cout // ekranda göster

    inpFile >> anket; cout

    Programın sonucu:

    Kolya, 1990, 582-78-95.

    Devam etmek için herhangi bir tuşa basın. . .

    1. Programda işlemi kullanmak mümkün mü?

    ios::giriş ve ios::çıkış

    • a) evet, her durumda;
    • b) evet, ancak yalnızca metin dosyalarıyla çalışırken;
    • c) Hayır, neyse.
    • 2. Bir metin dosyasını okumak üzere açmak için doğru seçeneği belirtin:
      • a) ifstream inpF("input.txt", ios::in);
      • b) ifstream inpF("input.txt", ios::input);
      • c) ifstream inpF(ios:in, "input.txt").

    H. Aşağıdaki kodu çalıştırmanın bir sonucu olarak ne görüntülenecek?

    girdiDosyası.get(c);

    sonraki - inputFile.peek();

    eğer (sonraki == EOF)

    • a) inputFile akışıyla ilişkili dosyanın içeriği bir kez görüntülenecektir;
    • b) inputFile akışıyla ilişkili dosyanın içeriği ekranda görüntülenecektir. sonsuz sayı bir kere;
    • c) ekranda hiçbir şey görüntülenmez.
    • 4. Dosyada kaç karakter var?
    • 12 3 4 5 6
    • bir) 6;
    • b) 7;
    • 11'de.
    • 5. Bir dosyanın sonunu belirlemenize hangi yöntemler olanak sağlar?
    • a) eof();
    • b) iyi();
    • c) bu yöntemlerin her ikisi de.
    • 6. getline() işlevinin amacı nedir?
    • a) bir dosyadan bir kelime okur;
    • b) dosyanın tüm içeriğini okur;
    • c) bir dosyadan bir satır okur.
    • 7. Kullanıcı tanımlı veri türlerini bir dosyaya yazmak/okumak için şunları yapmalısınız:
      • a) ">>" ve " işlemlerini aşırı yükleme
      • b) kullanıcı tanımlı veri tiplerinin yazılması ve okunması ek işlemler olmaksızın mümkündür;
      • c) kullanıcı tanımlı veri türlerinin bir dosyaya yazılması ve okunması mümkün değildir.
    • 8. Bilgileri ikili biçimde yazmak / okumak için hangi işlevler kullanılır?
    • a) printf/scanf
    • b) yazmak / okumak;
    • c) koy / al.
    • 1. İngiliz alfabesinin harflerini bir dosyaya yazan bir program yazın.
    • 2. input.txt dosyası birkaç metin satırından bilgi içerir. Bu dosyanın içeriğini ekranda görüntüleyin, dosyadaki satır sayısını sayın.
    • 3. Disk, kimyasal deneylerin sonuçlarını içeren sonuç.txt dosyasını içerir. Bu dosyanın copy_resylt.txt adlı bir kopyasını oluşturan bir program yazınız.
    • 4. Bir dosya adı girmek için klavyeyi kullanın. İÇİNDE belirtilen dosya tüm çift çizgileri kaldırın.
    • 5. Bir metin dosyasındaki tüm küçük harfleri büyük harflerle değiştiren veya tam tersini yapan bir program yazın.
    • 6. Kaynak metin dosyası, boşluklarla ayrılmış sayılar içerir. İki yeni dosya oluşturun: ilki yalnızca çift sayıları ve ikincisi - tek sayıları içermelidir.
    • 7. Dosya gerçek sayılar içermektedir. Bu sayıların kesirli kısımlarını çıkarıp yeni bir dosyaya yazan bir program yazınız.
    • 8. Havayolu uçuşları ile ilgili bilgiler bir metin dosyasına kaydedilir. Öğleden sonra kalkan uçuşları bu verilerden seçin ve ekranda görüntüleyin.
    • 9. >> ve işleçlerini aşırı yükleyin
    • 10. İkili dosyalarla çalışmak için kendi sınıfınızı yazın.
    • 11. Bir sınıftaki 10 öğrencinin listesini bir metin dosyasına ve bir ikili dosyaya yazın. Bu dosyaları karşılaştırın. Ortaya çıkan farkı açıklayın.
    • 12. Arabalarla ilgili bilgileri (üretim yılı, marka, renk vb.) bir dosyadaki bir metin dosyasına yazan bir sınıf geliştirin. Bu durumda, her bilgi sembolü kendi ABO 1 kodu ile değiştirilir. Ortaya çıkan dosyayı ekranda görüntüleyin.

    Kontrol soruları

    • 1. Dosya akışlarıyla çalışmak için hangi sınıflar kullanılır?
    • 2. Dosyalarla çalışırken hangi erişim modları kullanılabilir? Örnekler ver.
    • 3. Bir dosyayı açmak için hangi yöntem kullanılır? Örnekler ver.
    • 4. Dosyalarla çalışmak için hangi işlemler kullanılabilir? Bu işlemleri gerçekleştirmek için hangi işlevler tasarlanmıştır?
    • 5. Bir dosyadan bilgi okurken dosyanın sonunu belirlemenize hangi yöntemler olanak tanır? Bu yöntemler arasındaki fark nedir? Örnekler ver.
    • 6. Metin dosyalarından standart veri türlerinin değişkenleri nasıl okunabilir?
    • 7. Özel veri türlerinin değişkenlerini metin dosyalarından okumak mümkün müdür?
    • 8. Bir dosyadan rastgele bilgi okumak için hangi işlevler tasarlanmıştır? Örnekler ver.
    • 9. İkili dosyaların özelliklerini adlandırın. Bu tür dosyaları kullanmanın faydaları nelerdir?
    • 10. İkili dosyalara bilgi yazmak/okumak için hangi işlevler kullanılabilir?
    • 11. Bir ikili dosyadan standart veri türlerinin değişkenleri nasıl okunur?
    • 12. İkili dosyalardan özel veri türlerini okurken nelere dikkat edilmelidir?
    • "İvanov", 23), ("Sidorov", 21),

    Dosyaların tanımı ve dahili gösterimi

    Dosyalar farklı. Bir bilgisayarda depolanan tüm dosyaların özel nitelikleri vardır, örn. özel yollar bir dosyayı diğerinden ayırt etmek için açıklamalar: 1) ad; boyut 2; 3) tarih ve saat; 4)simge.

    Her dosyanın bir adı vardır - dosyanın adı. Dosya adı, içeriğini açıklar veya ne için kullanılabileceğini önerir. Ad, oluşturulduğunda dosyaya atanır. Bu tüm dosyalar için geçerlidir.

    Her dosyanın fiziksel bir boyutu vardır. Dosya biraz bilgisayar belleği ve biraz disk alanı kaplıyor.

    Bir dosya oluşturulduğunda, işletim sistemi dosyaya oluşturulma tarihi ve saatini damgalar. Bu, dosyaları tarih ve saate göre sıralamanıza ve böylece bilgisayarınızı temizlemenize olanak tanır. Dosyanın güncellendiği veya değiştirildiği tarih ve saat de not edilir.

    Her dosya, gördüğümüz dosya simgesiyle yakından ilişkili, belirli bir türdedir. Dosya türü, içeriğine bağlıdır. Her program, oluşturulan belgeye belirli bir tür ve karşılık gelen simge atar.

    Dosya boyutu, bellek miktarı gibi bayt cinsinden ölçülür.

    Dosya boyutu 0 bayt olabilir, bu da dosyanın var olduğu ancak kendi içinde hiçbir şey içermediği anlamına gelir. S En büyük boy dosya - 4 GB. Ancak bu kadar büyük dosyalar çok nadirdir.

    Bilgisayarın yerleşik saatine, özellikle dosyalara oluşturulma saatini ve tarihini atamak için ihtiyaç duyulur. Bu, bu saati doğru ayarlamanın ne kadar önemli olduğunu açıklıyor. Dosyaları açıklamak için ek nitelikler de vardır, örneğin sistem dosyaları, gizlenmiş dosyalar, salt okunur dosyalar, arşiv dosyaları vesaire. işletim sistemi bununla kendi başına ilgilen.

    Her dosyanın benzersiz bir dizini vardır. Dizin, herhangi bir işlemin dosyaya erişmek için ihtiyaç duyduğu bilgileri içerir. İyi tanımlanmış bir dizi kullanarak erişim dosyalarını işler. sistem çağrıları ve dosyanın, bileşik dosya adı olarak işlev gören bir karakter dizisi ile tanımlanması. Her bileşik ad, bir dosyayı benzersiz şekilde tanımlar, böylece çekirdek, adı bir dosya dizinine çevirir. Dizin, diskteki dosya bilgilerinin konumunun bir adres tablosunu içerir. Diskteki her blok numarasına göre adreslendiğinden, bu tablo disk bloğu numaralarının bir koleksiyonunu saklar. Daha fazla esneklik için çekirdek, bir dosyaya her seferinde bir blok ekleyerek dosyanın bilgilerinin dağılmasına izin verir. dosya sistemi. Ancak böyle bir düzen, veri bulma görevini zorlaştırır. Adres tablosu, dosyaya ait bilgileri içeren blok numaralarının bir listesini içerir, ancak basit hesaplamalar Dizindeki dosya bloklarının doğrusal listesini yönetmenin zor olduğunu gösterin. Küçük bir indeks yapısının çalışabilmesi için büyük dosyalar, disk bloğu adres tablosu yapısı ile uyumlu hale getirilir.

    Metin ve ikili dosyalar

    Dosyalar, kullanıcının büyük miktarda veriyi klavyeden yazmadan doğrudan diskten okumasına olanak tanır. İki ana dosya türü vardır: metin ve ikili.

    Metin herhangi bir karakterden oluşan dosyalar olarak adlandırılır. Her biri " karakteriyle biten satırlar halinde düzenlenmiştir. yolun sonu". Dosyanın sonu " simgesiyle gösterilir. dosyanın sonu". Herhangi bir program kullanılarak görüntülenebilen bir metin dosyasına bilgi yazarken Metin düzeltici, tüm veriler bir karakter türüne dönüştürülür ve karakter biçiminde saklanır.

    ikili olarak X Dosyalar bilgi, her tür ve yapıdaki veriyi depolayabilen, belirli büyüklükteki bloklar şeklinde okunur ve yazılır.

    Dosyalarla çalışmak için özel veri türleri kullanılır. Canlı Yayınlar. ifstream akışı, dosyalarla okuma modunda ve ifstream yazma modunda çalışmak için kullanılır. Hem yazma hem de okuma modlarında dosyalarla çalışmak için ifstream akışı kullanılır.

    C++ programlarında metin dosyalarıyla çalışırken ifstream ve iostream kitaplıklarını dahil etmek gerekir.

    Bir metin dosyasına veri yazmak için yapmanız gerekenler: 1) tarif etmek tip değişkeni akış dışı açık; 3) bir dosyaya çıktı bilgisi; 4) dosyayı kapattığınızdan emin olun.

    Bir metin dosyasından veri okumak için yapmanız gerekenler:

    1) bir tür değişkeni tanımlayın ifstream; 2) işlevi kullanarak dosyayı açın açık; 3) dosyadan bilgi oku, verilerin her bir bölümünü okurken dosyanın sonuna ulaşılıp ulaşılmadığını kontrol etmek gerekir; 4) dosyayı kapatın.

    Yukarıda tartışılan tüm örneklerde, "r" ve "w" modlarındaki fopen() işlevinin sırasıyla okuma ve yazma için bir metin dosyası açtığına dikkat edilmelidir. Bu, '\r' satırbaşı gibi bazı metin biçimlendirme karakterlerinin, dosyada nasıl bulunurlarsa bulunsunlar ayrı karakterler olarak okunamayacakları, ancak orada oldukları anlamına gelir. Bu, metin dosyası modunun bir özelliğidir. Dosyaların içeriğiyle daha "hassas" bir çalışma için, bir dosyanın içeriğini bir bayt dizisi olarak temsil eden ve olası tüm kontrol kodlarının yalnızca sayılardan oluştuğu bir ikili mod vardır. Metin modunda mevcut olmayan kontrol karakterlerini kaldırmak veya eklemek bu modda mümkündür. Bir dosyayı ikili modda açmak için, son parametresi okuma ve yazma için sırasıyla “rb” ve “wb” ye eşit olan fopen() işlevi de kullanılır.

    Şimdiye kadar ele aldığımız örnekler, dosyalara biçimlendirilmiş bilgi girişi / çıktısını göstermiştir. Biçimlendirilmiş dosya giriş/çıkış sayılarının yalnızca küçük ve küçük olmaları durumunda ve ayrıca dosyaların görüntülenmeden görüntülenmesinin gerekli olması durumunda kullanılması tavsiye edilir. yazılım araçları. Aksi takdirde, elbette, sayıları formda değil, bilgisayarın RAM'inde olduğu gibi depolayan ikili G/Ç'yi kullanmak çok daha verimlidir. karakter dizileri. Tamsayı (int) veya gerçek (float) değerin bellekte 4 bayt, çift değerin 8 bayt, karakter değerinin ise bellekte yer kapladığını hatırlatayım. char türünden- 1 bayt. Örneğin, bir metin (biçimlendirilmiş) dosyasındaki 12345 sayısı 5 bayt, ikili dosyada ise 4 bayt alır.

    ikili dosyalar, yani Bilgilerin dahili bir sunum biçiminde depolandığı dosyalar, yazılım araçları tarafından daha sonra kullanılmak üzere kullanılır; yazılım dışı araçlar tarafından görüntülenemezler. İkili dosyaların avantajı, birincisi, okurken / yazarken, verileri sembolik bir temsil biçiminden dahili ve tersine dönüştürmek için zaman harcanmaması ve ikincisi, doğruluk kaybı olmamasıdır. gerçek sayılar. Hem biçimlendirilmiş G/Ç durumunda hem de ikili G/Ç durumunda, bir dosyadaki bilgilerin "doğru" işlenmesi için, hangi tür verilerin, nasıl ve hangi sırayla yazıldığını bilmek gerekir. ikili dosya, özellikle ikili dosyayı bir metin düzenleyiciyle görüntülemek hiçbir şey yapmayacağından.

    Tamsayı öğelerinin yazılmasını gösteren bir örnek düşünün dinamik dizi bir ikili dosyaya ve bu dosyadan okuma.

    #katmak

    #katmak

    #katmak

    ad alanı std kullanarak;

    cout<< "Vvedite kol-vo elementov celochisl. massiva: "; cin >>H;

    int *mas = yeni int[N];

    için(i=0; ben

    cout<< " Vvedite " << i << "-i element: "; cin >> ma[i];

    cout<< "\nIdet zapis dannyh v fail..." << endl;

    akış fout("c:\\os\\bin.dat", ios::binary);//yaratmak. dışarı. ikili akış

    if(!fout) ( cout<< "\n Oshibka otkrytiya faila!"; getch(); return 1; }

    fout.write(reinterpret_cast (kütle), N*sizeof(int));//diziyi dosyaya yaz

    fout.close();// akışı kapatıyoruz

    cout<< "Dannye uspeshno zapisany!" << endl;

    için(i=0; ben

    ifstream fin("c:\\os\\bin.dat", ios::binary); // dosyayı okumak için bir akış oluştur

    if(!fin) ( cout<< "\n Oshibka otkrytiya faila!"; getch(); return 1; }

    cout<< "Fail sodergit:" << endl;

    fin.read(reinterpret_cast (kütle), N*sizeof(int));//diziyi dosyadan oku

    için(i=0; ben

    getch(); 0 dönüşü;

    Bu programda write() (ofstream sınıf yöntemi) ve read() (ifstream sınıf yöntemi) işlevlerinin kullanımına özel dikkat gösterilmelidir. Bu işlevler, verileri bayt cinsinden düşünür ve belirli sayıda baytı veri arabelleğinden dosyaya ve geri aktarmak için tasarlanmıştır. Bu işlevlerin parametreleri ara belleğin adresi ve bayt cinsinden uzunluğudur.

    write() işlevi, birinci parametrede belirtilen sayıdan ikinci parametrede belirtilen bayt sayısını dosyaya yazmak için tasarlanmıştır. adresler veri arabelleği ve read() işlevi bir dosyadan veri okumak için tasarlanmıştır. Burada, bu işlevlerin yalnızca char türünde bir veri arabelleği ile çalıştığına dikkat edilmelidir. Bu bağlamda, bu programda operatörü kullandık. yeniden yorumlamak<> int (mas) türündeki veri arabelleğimizi char türündeki bir arabelleğe dönüştürür.

    Unutulmamalıdır ki operatör kullanılarak yapılan döküm tipi yeniden yorumlamak yalnızca işlevlerin ilk parametresinin olduğu durumlarda gereklidir yazmak() Ve Okumak() bir karakter dizisi değildir (sonuçta, bir tür karakter karakter sadece 1 bayt yer kaplar). Ek olarak, bir dizi değil, bireysel değişkenler yazmanız veya okumanız gerekiyorsa, o zaman referans mekanizmasını kullanmanız gerekir (veri arabelleğinin adresine referans), örneğin:

    akış fout(dosya adı, ios::app | ios::binary);

    fout.write(reinterpret_cast (& cb), sizeof(float));

    Şimdi, ele alınan fonksiyonların ikinci parametresini tartışmak gerekiyor. Bu programda ikinci parametre olarak bayt sayısını hesapladığımız N * sizeof (int) ifadesini kullandık. Örneğin, 5 tamsayı dizi elemanımız varsa, bayt sayısı 20 olacaktır. sizeof() işlevi, parametre olarak belirtilen veri türü için ayrılan bayt sayısını döndürür. Örneğin, sizeof( int) 4 döndürür.

    Yani bu örnekte verilen program bin.dat dosyasına binary formda veri yazmanıza ve bu binary dosyadan okumanıza olanak sağlıyor. Ayrıca bu veriler okunduktan sonra int tipine çevrilir, array yapısı kazanır ve bunlarla her türlü işlem yapılabilir.

    Şimdi, bin.dat dosyasından veri okumanıza izin veren bir program yazmanız gerektiğini hayal edin ve bu dosyanın yalnızca ikili biçimde bir tamsayı dizisinin öğelerini içerdiğini biliyoruz. Kaydedilen öğelerin sayısı ( N ) Biz bilmiyoruz. Bir program oluştururken sabit bir dizi kullanma hakkımız yoktur, yani. program oluşturma aşamasında bunun için bellek ayırın. Bu hatalı bir sonuç verecektir. Çok küçük bir N değeri, dizinin tüm öğelerinin dikkate alınmamasına ve çok büyük bir N değeri, fazladan hücrelerin rastgele değerlerle doldurulmasına yol açacağından.

    Belleği dinamik olarak ayırarak bir tamsayı dizisinin öğelerini bir ikili dosyadan okumanıza ve okunan verilerin gerçekçiliğini kanıtlamanıza, toplamlarını hesaplamanıza izin veren bir program örneğini düşünün.

    #katmak

    #katmak

    #katmak

    ad alanı std kullanarak;

    int N, i, toplam=0, dfb; //dfb - bayt cinsinden dosya uzunluğu

    ifstream fin("c:\\os\\bin.dat", ios::ikili);

    if(!fin) ( cout<< "Oshibka otkrytiya faila!"; getch(); return 1; }

    fin.seek(0, ios::end);//okuma konumunu dosyanın sonuna ayarla (0 baytın sonundan itibaren)

    dfb = fin.tellg();//dosya konum değerinin sonu alın (bayt olarak)

    N=dfb/4;//bir tam sayının 4 bayt alacağını bildiğimize göre sayıların sayısını hesaplıyoruz

    int *arr = yeni int[N];// dinamik bir dizi oluştur

    fin.seekg(0, ios::beg);//verileri okumadan önce mevcut konumu dosyanın başına taşı

    fin.read(reinterpret_cast (arr), dfb);

    cout<< "Iz faila schitano " << N << " elementov:" << endl;

    için(i=0; ben

    için(i=0; ben

    cout<< "\n Ih summa = " << sum;

    getch(); 0 dönüşü;

    ifstream sınıfının metotları olanseeng() ve tellg() fonksiyonlarını aktif olarak kullandığımız bu programa yakından bakalım. Burada belirtmek gerekir ki herhangi bir dosya açıldığında sözde geçerli okuma veya yazma konumuyla ilişkilendirilir. Bir dosya okumak için açıldığında, bu konum varsayılan olarak dosyanın başına gelir. Ancak, dosyada rastgele bir konumdan başlayarak okuyabilmek ve yazabilmek için çoğu zaman konumun manuel olarak kontrol edilmesi gerekir. searchg() ve tellg() işlevleri geçerli okuma işaretçisini ayarlamanıza ve kontrol etmenize izin verirken, search() ve tellp() işlevleri aynı şeyi yazma işaretçisi için yapar.

    search(1_parameter, 2_parameter) yöntemi, geçerli okuma konumunu dosyadan 2_parameter'de belirtilen konuma göre 1_parameter'de belirtilen bayt sayısı kadar taşır. 2_parameter üç değerden birini alabilir:

    ios::beg - dosyanın başından itibaren;

    ios::cur - geçerli konumdan;

    ios::end - dosyanın sonundan.

    Burada beg, cur ve end ios sınıfında tanımlanan sabitlerdir ve:: sembolleri bu sınıfa erişim işlemini belirtir. Örneğin, operatör fin.seekg(-10, ios::end); dosyanın bitiminden 10 bayt önce dosyadan geçerli okuma konumunu ayarlamanıza olanak tanır.

    Şimdi programın açıklamasına geri dönelim. Dosyaya yazılan sayıların sayısını bilmediğimizden hareketle öncelikle sayıların sayısını bulmamız gerekiyor. Bunun için kullanarak fin.seek(0, ios::end); dosyanın sonuna gidiyoruz ve dosyanın uzunluğunu bayt cinsinden dfb değişkenine döndürmek için tellg() işlevini kullanıyoruz. tellg() işlevi, işaretçinin geçerli konumunu bayt cinsinden döndürür. Bayt cinsinden bir tamsayının uzunluğu bizim tarafımızdan bilindiğinden (4 bayt), dosyanın bayt cinsinden uzunluğunu bilerek dosyaya yazılan sayıların sayısını hesaplamak zor değildir ( N=dfb/4;). Sayı sayısını öğrendikten sonra, read () işlevini kullanarak verileri okumaya başlamak için dinamik bir dizi oluşturur ve dosyanın başına gideriz. Tarafımızdan belirtilen sayıda veri baytı (dfb) veri arabelleğine (arr) aktarıldıktan sonra bu şekilde okunan veriler bir dizi yapısı kazanır ve her türlü işlem ve dönüşüm için tam uygun hale gelir.

    kayıtlar), o zaman kullanılmayan, ancak kullanılan bellek miktarını bir şekilde azaltmak istemek oldukça anlaşılır bir durumdur.

    Bu tür durumlar için var değişken parçalı girişler.

    Varyant kısmı ile kayıt açıklaması

    Var bölümünde değişken parçalı notasyonşöyle tarif et:

    var<имя_записи>: kayıt<поле1>: <тип1>; [<поле2>: <тип2>;] [...] dava<поле_переключатель>: <тип>ile ilgili<варианты1>: (<поле3>: <тип3>; <поле4>: <тип4>; ...); <варианты2>: (<поле5>: <тип5>; <поле6>: <тип6>; ...); [...] son;

    Varyant olmayan kısım girişler (büyük/küçük harf anahtar kelimesinden önce) normal bir girişle aynı kuralları izler. Genel olarak konuşursak, değişken olmayan kısım tamamen olmayabilir.

    Varyant parçası ayrılmış kelime durumu ile başlar, ardından daha sonra bir anahtar görevi görecek olan kayıt alanı belirtilir. Normal bir case ifadesinde olduğu gibi, anahtar aşağıdakilerden birine ait olmalıdır. numaralandırılmış türler veriler (bkz. ders 3). Seçim listesi bir sabit, bir aralık veya birkaç sabit veya aralığın birleşimi olabilir. Karşılık gelen seçenek yürütüldüyse, kayıt yapısına dahil edilmesi gereken alan kümesi parantez içine alınır.

    Örnek. Kütüphanenin içeriğini açıklamak için aşağıdaki bilgiler gereklidir:

    "Başlık" ve "Yayıncı" sütunları her üç seçenek için ortaktır ve geri kalan alanlar yayın türüne bağlıdır. Bu yapıyı uygulamak için kullandığımız değişken parçalı notasyon:

    biblio yazın = kayıt adı, yayıncı: dize; vaka öğesi: char of "b": (yazar: dizi; yıl: 0..2004); "n": (veri: tarih); "m": (yıl: 1700..2004; ay: 1..12; sayı: tamsayı); son;

    Öğe alanının değerine bağlı olarak, kayıt 4, 5 veya 6 alan içerecektir.

    Değişken parçalı bir kayıt kullanma mekanizması

    Derleyici tarafından tahsis edilen bayt sayısı değişken parçalı notasyon, en uzun varyantı tarafından belirlenir. Diğer seçeneklerden "daha kısa" alan kümeleri, ayrılan belleğin yalnızca bir kısmını kaplar.

    Yukarıdaki örnekte "b" seçeneği "en uzun"dur: 23 bayt gerektirir (bir dize için 21 bayt ve bir tamsayı için 2 bayt). "n" ve "m" seçenekleri sırasıyla 4 ve 5 bayt gerektirir (tabloya bakın).

    isim, yayıncı öğe Varyant parçası
    ... "B" yazar yıl
    ... "N" veri
    ... "M" yıl ay sayı
    ... "B" yazar yıl

    ikili dosyalar

    İkili dosyalar, bilgileri bilgisayarın belleğinde sunulduğu biçimde depolar ve bu nedenle insanlar için elverişsizdir. Böyle bir dosyaya bakıldığında içinde ne yazdığını anlamak imkansızdır; manuel olarak - bazı metin düzenleyicilerde - oluşturulamaz veya düzeltilemez vb. Ancak, tüm bu rahatsızlıklar, verilerle çalışma hızı ile telafi edilir.

    Ayrıca, metin dosyaları yapılardır sıralı erişim ve ikili - doğrudan. Bu, yalnızca geçerli öğeye değil, istediğiniz zaman herhangi birine başvurabileceğiniz anlamına gelir.