Zapisywanie tablicy typu double w pliku binarnym i tekstowym + odczyt

0

Witam,

Mam problem ze swoim programem. Program umożliwia kopiowanie tablicy do pliku binarnego i tekstowego, odczyt.
Zapis i odczyt tekstowego moim zdaniem jest dobrze, ale coś z plikiem binarnym mi nie pasi.
Plik zajmuje zbyt dużo miejsca, dla 10k elementów tablicy powinien zajmować około 30KB a zajmuje ponad 70KB, a za to tekstowy 54KB.
Może ktoś zobaczyć co jest nie tak z tym programem.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class Pliktxt
    {
        public static void Odczyt(string Nazwa) // odczytywanie pliku tekstowego
        {
            FileStream Strumień;
            StreamReader Odczyt;
            string Odczytane;
            Odczytane = "";
            Strumień = new FileStream(Nazwa, FileMode.Open, FileAccess.Read);
            Odczyt = new StreamReader(Strumień);
            Odczytane = Odczyt.ReadToEnd();//Odczytywanie całego tekstu
            Console.WriteLine(Odczytane);
            Odczyt.Close();
            Strumień.Close();
        }

        public static void Zapis(string Nazwa, double[]Tablica, int indeks) //zapisywanie do pliku tekstowego
        {
            FileStream Strumień;
            StreamWriter Zapis;

            Strumień = new FileStream(Nazwa, FileMode.Append, FileAccess.Write);
            Zapis = new StreamWriter(Strumień,Encoding.UTF8);
            for (indeks = 0; indeks < Tablica.Length; indeks++)
                Zapis.WriteLine(Tablica[indeks]);
            Zapis.Close();
            Strumień.Close();
        }
    }

    class Plikbin
    {
        public static void ZapiszBinarnie(string Nazwa, double[]Tablica, int indeks)
        {
            FileStream Strumień;
            BinaryWriter Zapis;
            Strumień = new FileStream(Nazwa, FileMode.Append, FileAccess.Write);
            Zapis = new BinaryWriter(Strumień);
            for (indeks = 0; indeks < Tablica.Length; indeks++)
                Zapis.Write(Tablica[indeks]);
            Zapis.Close();
            Strumień.Close();
        }

        public static void odczytbinarnie(string Nazwa)
        {
            FileStream Strumień;
            BinaryReader Odczyt;
            double wypisz;
            int length; 

            Strumień = new FileStream(Nazwa, FileMode.Open, FileAccess.Read);
            Odczyt = new BinaryReader(Strumień);
            length = (int)Odczyt.BaseStream.Length;

            while (Odczyt.PeekChar() != -1)
            {
                wypisz = Odczyt.ReadDouble();
                Console.WriteLine(wypisz);
            }

            Odczyt.Close();
            Strumień.Close();
        }
       
    }

    class Program
    {
        static void Main(string[] args)
        {
            double[] Tablica;
            int i;
            double liczbawylosowana;
            Random Generator;
            string Pliktekst;
            string Plikbinarny;
            int opcja;
            int kontrol;

            opcja = 0;
            kontrol = 0;
            Pliktekst = "Ptekstowy.txt";
            Plikbinarny = "Pbinarny.bin";
            Generator = new Random();
            i = 0;
            liczbawylosowana = 0;
            Tablica = new double[10000];

            for (i = 0; i < Tablica.Length; i++) //generator losowej tablicy
            {
                liczbawylosowana = Generator.Next(10000);
                Tablica[i] = liczbawylosowana;
            }

            do
            {
                kontrol = 0;
                Console.Clear();

                Console.WriteLine("Wybierz opcje:\n1. Zapisuje tablice do pliku tekstowego\n2. Odczytuje plik tekstowy");
                Console.WriteLine("3. Zapisuje tablice do pliku binarnego\n4. Odczytuje plik binarny");
                Console.WriteLine("5. Przepisywanie z pliku takstowego do binarnego\n6. Przepisywaie z pliku binarnego do tekstowego");
                opcja = Convert.ToInt32(Console.ReadLine());
                switch (opcja)
                {
                    case 1:
                        {
                            Console.Clear();
                            Pliktxt.Zapis(Pliktekst, Tablica, 0);
                            Console.WriteLine("Plik został zapisany");
                            break;
                        }
                    case 2:
                        {
                            Console.Clear();
                            Pliktxt.Odczyt(Pliktekst);
                            break;
                        }
                    case 3:
                        {
                            Console.Clear();
                            Plikbin.ZapiszBinarnie(Plikbinarny,Tablica,0);
                            Console.WriteLine("Plik został zapisany");
                            break;
                        }
                    case 4:
                        {
                            Console.Clear();
                            Plikbin.odczytbinarnie(Plikbinarny);
                            break;
                        }
                    case 5:
                        {
                            break;
                        }
                    case 6:
                        {
                            break;
                        }
                    default:
                        {
                            Console.WriteLine("Zła opcja, wcisnij 1 aby wrocic do menu");
                            break;
                        }
                }
                        Console.WriteLine("Aby wrocic do menu nacisnij 1, aby wyjsc nacisnij dowolny klawisz");
                        kontrol = Convert.ToInt32(Console.ReadLine());
                
            } while (kontrol == 1);

           
            Console.ReadKey();
        }
    }
}

 
0

10k liczb double, każda po 8 bajtów (64 bity), to razem 80kB.

0

Hmm... możliwe. Czyli w takim razie nie ma błędu? To czemu plik binarny zajmuje więcej miejsca niż tekstowy (oba zawierają ta samą tablicę), bo to chyba binarny powinien miej miejsca zajmować, prawda?

0

Niekoniecznie. Generujesz całkowite liczby od 0 do 10000. Taka liczba to średnio niecałe 4 cyfry. Do zapisu tekstowego potrzeba więc 4 znaki z zakresu '0' - '9'. W UTF-8 znaki te zajmują 1 bajt każdy. Dodatkowo liczby oddzielasz znakami nowej linii - po dwa bajty każdy (\r\n). Stąd 10k * (4 + 2) B = 60kB (niecałe bo niektóre liczby będą miały mniej niż 4 cyfry).

0

Faktycznie, dziękuje za wytłumaczenie.
Zmieniłem żeby teraz losowało mi liczby z zakresu 0.0-1.0

liczbawylosowana = Generator.NextDouble();

i teraz jest widoczna różnica dla tych 10k elementów tablicy.
Plik tekstowy: 186KB
Plik binarny: 79KB

Dziękuje serdecznie za podpowiedzi i wytłumaczenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1