Diskuze: Čtení/zápis bitů z/do souboru
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 11 zpráv z 11.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
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ší.
Potřebuji to rozdělit na jednotlivé bity, takže do stringu získat data
souboru v 1 a 0
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ší?
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.
Človek by se divil, kde se to takto používá. Například firma Lattice
má soubory firmwarů opravdu zapsané 0 a 1 textově
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.
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.
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.
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;
}
Zobrazeno 11 zpráv z 11.