Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Čtení/zápis bitů z/do souboru

Aktivity
Avatar
Neaktivní uživatel:8.8.2019 18:47

Ahoj,

potřebuji číst a zapisovat v bity z/do souboru, jak to mám udělat jednoduše a efektivně? S bity potřebuji pracovat v datovém typu std::string, soubory mohou mít i desítky MB.

Děkuji za odpověď :)

Zkusil jsem: Googlit, něco jsem našel ale moudrý z toho nejsem :)

Chci docílit: Čtení/zápis bitů z/do souboru v C++

Odpovědět
8.8.2019 18:47
Neaktivní uživatelský účet
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Neaktivní uživatel
ostrozan:10.8.2019 16:16

A už jsi slyšel o tom, že soubor je vlastně jen dlóóóóuhá řada bitů nakrájená po osmi na bajty a kousek té řady se jmenuje hlavička, ve které je zapsáno, jak se ta řada má nasekat na kousky a co s těma kouskama udělat?
Takže jakýkoliv zápis /čtení splňuje tvé požadavky - pokud teda nebudeš konkrétnější.

 
Nahoru Odpovědět
10.8.2019 16:16
Avatar
Odpovídá na ostrozan
Neaktivní uživatel:10.8.2019 20:34

Potřebuji to rozdělit na jednotlivé bity, takže do stringu získat data souboru v 1 a 0 :)

Nahoru Odpovědět
10.8.2019 20:34
Neaktivní uživatelský účet
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Neaktivní uživatel
ostrozan:10.8.2019 22:23

Takže raw data souboru převést na textový soubor s nulama a jedničkama ?
K čemu je to dobré, kromě toho, že soubor bude osmkrát větší?

 
Nahoru Odpovědět
10.8.2019 22:23
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Neaktivní uživatel
DarkCoder:10.8.2019 22:51

Hodnoty 0 a 1 představující bitové hodnoty, které jsou uloženy v souboru, jsou stále brány jako znak. Takže způsob čtení nebo zápisu "klasického" znaku nebo znaku odpovídající 0 nebo 1, je úplně stejný. Spíše bych řekl že potřebuješ převádět klasický text do binární podoby a naopak, obsah souboru tvořený z 0 a 1 zpět na text.

Jádrem toho všeho je umět převést znak do binární podoby.

for (int i = CHAR_BIT - 1; i >= 0; i--) cout << ((c >> i) & 1);

Převod celého textu je už alternativa doplněná o traversing souboru nebo řetězce, podle toho odkud znaky vytahuješ.

Následující kód ukazuje výpis binární reprezentace řetězce na obrazovku.

unsigned char text[] = "www.itnetwork.cz", *ptext = text;
while (*ptext) {
        for (int i = CHAR_BIT - 1; i >= 0; i--) cout << ((*ptext >> i) & 1);
        ptext++;
}

Ve svém případě akorát provedeš změny v traversování souboru nikoli řetězce a zápisu do řetězce, nikoli na obrazovku.

Nahoru Odpovědět
10.8.2019 22:51
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na ostrozan
Erik Šťastný:11.8.2019 9:24

Človek by se divil, kde se to takto používá. Například firma Lattice má soubory firmwarů opravdu zapsané 0 a 1 textově :D

 
Nahoru Odpovědět
11.8.2019 9:24
Avatar
Caster
Člen
Avatar
Caster:12.8.2019 7:05

Proč nějaké konverze ? Alokuj si potřebný prostor v paměti a pak ho celý čti/zapiš do souboru. Velikost souboru "desítky MB" nejsou žádný problém. Sám pracuji s textovým souborem 4 GB, který načtu najednou do paměti a pak s ním pracuji.

 
Nahoru Odpovědět
12.8.2019 7:05
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Caster
Peter Mlich:12.8.2019 9:32

Pokud s tim souborem moc casto nepracujes (vetsinu casu slouzi pro cteni), tak jej muzes na disku zabalit do zipu. Zipovani je dnes pomerne rychla zalezitost.

 
Nahoru Odpovědět
12.8.2019 9:32
Avatar
Caster
Člen
Avatar
Odpovídá na Peter Mlich
Caster:12.8.2019 9:56

Načtení souboru 4 GB trvá cca 2,5 sekundy, zipování není potřeba. S daty (38 mil. řádků/GPS souřadnic) pak pracuji v RAM. Program v C++ volá funkce v ASM 64bit. Zpětné hledání trasy mořských bójí (cca 23 000) v Indickém oceánu z 12ti míst v cyklu (80 až 108 E, 0 až 40 S po 1°) je otázkou několika sekund včetně vynesení jejich tras na mapě. Data jsem si předem setřídil, převedl na integer hodnoty a hledám je půlením intervalu.

 
Nahoru Odpovědět
12.8.2019 9:56
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Caster
Peter Mlich:12.8.2019 12:17

Ok.
Jen jsem chtel rici, ze, pokud ten soubor mas na disku, tak by mohlo byt efektivni pouzit zip i za cenu o 10% pomalejsiho nacteni.
Pro to, co popisujes, bych pouzil databazi a sql prikazy (casy v milisekundach). Import do db ale chvili trva u 4GB.

 
Nahoru Odpovědět
12.8.2019 12:17
Avatar
Caster
Člen
Avatar
Odpovídá na Peter Mlich
Caster:13.8.2019 20:28

Jak na čtení velkých souborů a alokaci paměti prakticky, část z mého programu:

const wchar_t *fname = L"C:\\Users\\Jan\\Soubor.txt";
__int64 delka = 0;
__int64 nacteno = 0;
const DWORD cti_blok = 2501566399;
BYTE* ptr = NULL;
BYTE* bsrc = NULL;
unsigned __int64 adresa = 0;
int radku = 0;
...
delka = FileSize(fname); // 64 bitů

        //* Zkusíme otevřít soubor pro čtení *//
        HANDLE handle = CreateFile(fname, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
        //if (handle == INVALID_HANDLE_VALUE)
        //      report_error("Unable to open input file!\n");


        //* Alokujeme pamět pro celý soubor *//
        static const SIZE_T giga = 1024 * 1024 * 1024;
        static const SIZE_T size = 5 * giga;
        ptr = static_cast<BYTE*>(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
        bsrc = ptr;

        //* Načteme soubor *//
        DWORD bytes_read;
        cti_znaku = cti_blok;
        do {
                BOOL e = ReadFile(handle, ptr, cti_znaku, &bytes_read, nullptr);
                nacteno += bytes_read;
                ptr += bytes_read;
                if (delka - nacteno < cti_blok) {
                        cti_znaku = delka - nacteno;
                }
        } while (nacteno < delka);
        CloseHandle(handle);

        // Upravíme načtená data v poli
        adresa = (unsigned __int64)bsrc;
        radku = nacteno / 125;                                  // Pro úpravu dat v C++
        __int64 result = Funkce_Uprav(adresa);
        ...
_int64 FileSize(const wchar_t* name)
{
        WIN32_FILE_ATTRIBUTE_DATA fad;
        if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
                return -1; // error condition, could call GetLastError to find out more
        LARGE_INTEGER size;
        size.HighPart = fad.nFileSizeHigh;
        size.LowPart = fad.nFileSizeLow;
        return size.QuadPart;
}
 
Nahoru Odpovědět
13.8.2019 20:28
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.