» »

[C] težava z binarnimi datotekami

[C] težava z binarnimi datotekami

darkkk ::

Nekaj se mučim z binarnimi datotekami, vendar že v osnovi neki jebe: namreč tole naj bi vpisani niz napisalo v binarno datoteko (zato "wb"), vendar zna notepad tole lepo prebrati, namesto nekih ljudem neberljivih krac... Zdaj pa ne vem ali je notepad tolk pameten, da zna brat binarne datoteke, vista lomi, mingw lomi ... HALP !

PS: includane zadeve so v primernih oklepajih, ki jih forum/html ne mara, poleg tega mi v končnem času ni uspelo uporabiti oglatih oklepajev s st.koda c.




#include stdio.h
#include stdlib.h

#define MAX 1000

int main (void){
char izraz[MAX];
FILE *f;
int len;


printf("vpisi izraz dolzine %d: \n >", MAX);
if ( fgets ( izraz, MAX, stdin ) != NULL )
fputs ( izraz, stdin );

len = strlen(izraz);
izraz[len] = '\0';

f = fopen("output.b", "wb");
fwrite(izraz,strlen(izraz),1,f);
fclose(f);

return 0;
}
  • spremenil: darkkk ()

krho ::

Če iz stdin prebereš besedilo in ga zapišeš v datoteko je še vedno to besedilo.
si.Mail odprto-kodni odjemalec elektronske pošte. - http://www.simail.si
Uredite si svojo zbirko filmov, serij in iger - http://xcollect.sf.net

fiction ::

Iz fopen() manuala:
The mode string can also include the letter ‘‘b’’ either as a last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with C89 and has no effect; the ‘‘b’’ is ignored on all POSIX conforming systems, including Linux. (Other systems may treat text files and binary files differently, and adding the ‘‘b’’ may be a good idea if you do I/O to a binary file and expect that your program may be ported to non-Unix environments.)

Torej ce das tja notri 'b' ali pa ne nima veze. To je misljeno samo, ce obstaja (oz. bi kdaj obstajal) kaksen OS, ki bi striktno loceval med datotekami s tekstom in drugimi datotekami. Drugace je to bolj kot komentar zate s kaksno vsebino bos imel opravka.

Tako kot je rekel krho: ce zapises A v datoteko bodo tam notri pac biti 01000001 (po ASCII abecedi). Ko to preberes
(na kakrsenkoli nacin) bos prebral znak 'A', ki pa ga lahko interpretiras kot stevilo 65 kot znak 'A' ali pac kakorkoli
hoces. Nima pa to veze z branjem iz datoteke.

darkkk ::

Rad bi naredil neko verzijo tegale:
Run-length encoding @ Wikipedia

Preprosto odpre datoteko, stisne.(Random datoteka bo verjetno dvakrat večja, samo to so odvečni detajli).

Isto stisnjeno datoteko odpre in predela nazaj.

Idejno naj bi potem v stisnjeni datoteki "živeli" pari (int,char), samo se še nisem lotil zares, tko da če ma kdo kak dobr predlog kako obiti težavo, če je v bin. datoteki cifra itd. Tudi kak dobr link o binarnih datotekah in kaj/kako je notri napisano bi bil dobrodošel.

Zgodovina sprememb…

  • spremenil: darkkk ()

Senitel ::

In kaj je težava?

BigWhale ::

Ja, naredi takole: Preberi string in ga zacni parsati.

Ce bos imel v stringu Halooooo??? To potem zapises kot "Hal<Marker>5o<Marker>3?"

darkkk ::

Mjah tezava je da sm n00b :p

Pač problem je, k pojma nimam kako sploh binarna datoteka zgleda, branje le tega itd.

Pač ne moreš glih uporabit nekega znaka za marker, če le ta nastopa v datoteki. Uporaba česarkoli daljšega od enega znaka pa se zdi "potratno". Oz. kaj se zgodi, če moraš kompresirati/dekompresirati "marker".

Mam pa dobro idejo kako okol tega: lepo bom uvedu strukturo {char counter, char znak}, en bo lepo znak, drug bo štel ponovitve in lepo to zmečem v novo datoteko. Dekompresija je pol čist izi, ker veš da imaš tolkpatolk ponovitev strukture notri. (mnjah neki podobnega serializaciji).

fiction ::

Ce imas vedno (znak, stevilo) ni problema. Samo potem moras paziti da bo npr. znak 1 bajt in stevilo 1 bajt. Ce hoces napisati 256 A-jev, moras to narediti kot A, 255, A, 1. Druga tezava je v tem, da se ti posamezen znak v besedilu shrani kot 2 bajta - kar ti prakticno unici "kompresijo".

Lahko se izognes temu in en A napises samo kot A, samo potem pride do problema ker za naprej ne ves vec kaj je znak in
kaj stevilo ponovitev. Jasno, ce imas omejeno mnozico tega kar enkodiras ni problema (npr. da tvoje pravilo velja samo
za A-Z - potem ko naletis na stevilko takoj ves, da je tisto stevilo ponovitev in ne vhodni znak).

Da se uporabiti varianto, ki je opisal BigWhale, navadne znake pustis pri miru, tisto kjer bos uporabil tvoj zapis (znak, stevilo) pa posebej oznacis. Samo tukaj tudi lahko pride do problema ker je <Marker> naceloma en cisto navaden znak. Isto kot prej: ce tega znaka ni nikjer v originalnem besedilu imas sreco, drugace pa moras "escapati" v stilu <Marker><Marker> v izhodni datoteki je dejansko samo en dejanski znak <Marker> ali kaj podobnega.

BigWhale ::

Ja, pri RLEju je tako, da je precej odvisen od tega kaj komprimiras in kaksno varianto RLEja vzames. Poglej si Applovo verzijo RLEja, imenuje se PackedBits. Stvar je preprosta in v dolocenih primerih zelo ucinkovita, se posebej, ce ves kaj komprimiras.

Jaz bi stvar naredil tako, da bi uporabil dva markerja. Enega, ki oznacuje komprimiran blok in enega, ki oznacuje nekomprimiran blok. Odlocis se koliksna bo maksimalna dolzina bloka in kaksna bo minimalna dolzina tistega kar bos pakiral. Ce uporabljas packed bits potem vzames kot maximalno dolzino bloka 127 bytov. En byte uporabis kot marker za to koliko bytov bo sledilo in ali bodo pakirani ali nepakirani. Tako se izognes preveliki izgubi kompresije, ce imas veliko stevilo bytov, ki jih ne mores stiskat in izognes se precej problemom pri branju komprimirane datoteke.

Stvar gre potem takole za zgoraj navedeni string Halooooo???

Najprej preberes string in potem stejes znake, vedno imas zalogo treh znakov, to je najmanj kar se ti se splaca stiskati. Ko preberes tri male Oje, vidis, da se to ze splaca stiskati. V file zapises -3, kar pomeni, da bodo sledili trije nekomprimirani byti. Potem beres naprej in preberes 5 ojev. Nato v file zapises 5 (pozitivna vrednost!) in 'o' kar pomeni, da bo petki sledil en znak, ki ga bos potem petkrat ponovil. Nato naredis se isto z zadnjimi tremi vprasaji.

Problem packed bits (ali katerekoli druge RLE kompresije) je v tem, da stopnja kompresije pada z vecanjem stevila blokov in v primeru precej nakljucnih podatkov pride do negativne kompresije. Recimo text. :)

darkkk ::

Spacal skupi RLE na koncu. Po pričakovanjih na random mp3 postane zadeva mal manj kot x2, na kaki "special" datoteki pa relativno majhna.

Pomoje bom probal še kako marker varianto kasneje ali pa še kaj bolj zvitega(BigWhale me je zdražu).

Je pa neverjetno koliko pozabim, če ne uporabljam. :/


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Compress

Oddelek: Znanost in tehnologija
332727 (2081) nevone
»

Branje binarne datoteke v polje znakov - C++

Oddelek: Programiranje
81801 (1669) Tutankhamun
»

[Naloga] : Max kompresija testne datoteke

Oddelek: Programiranje
343124 (2048) StratOS
»

delo z nizi

Oddelek: Programiranje
162983 (2527) tx-z
»

[Winsock & C++]HTTP - Prenašanje binarne datoteke - recv()

Oddelek: Programiranje
71247 (1166) W3by

Več podobnih tem