« 1 2 »
Autor Zpráva
honkytonk
Profil *
Dá se v PHP udělat, abych mohl načíst určitý počet bytů ze souboru, od určité pozice?

Dejme tomu, že chci do souboru ukládat data po 250x(3x250) bytů. A když chci načíst blok vypočítám si nejdříve pozici bloku. Příklad: chci načíst block n=120. zacatek_bloku=(n-1)*(3x250)=(119)*(3x250)=89250. konec_bloku=(n)*(3x250)=(120)*(3x250)=90000 . Prostě aby se načtení provedlo od bytu 89250 až po 90000.
Chro
Profil
Tohle řeší funkce fread, viz
http://php.net/manual/en/function.fread.php
a parametry handle (od) a length (délka, velikost).


EDIT:
Handle se posunuje funkcí fseek.
http://www.php.net/manual/en/function.fseek.php
honkytonk
Profil *
fread znám, ale ten fseak neznám, respektive kdysi jsem ho myslím párkrát použil, ale pak zapoměl že existuje. Dík
Chro
Profil
Ok, nezapomeň, že pro čtení bytů (ne znaků) musíš ve fopen použít přívlastek "rb".
honkytonk
Profil *
Ještě by se hodil nějaký odkaz na to jak ošetřit jedinečný přístup do souboru pro zápis. Například kdybych chtěl přidat nějaké data, aby to mezitím někdo jiný nepřepsal.
Chro
Profil
Pojem obecně se nazývá atomicita operací. Základ najdeš na
http://php.vrana.cz/atomicita-operaci.php
Pochopil jsem to ve směru zápis do souboru, zda jde i o čtení si musíš vyzkoumat sám. Zas takový expert nejsem. A hledat to více Googlem se mi nechce. Jsou 3 ráno a mám slušně naváto. ;-)
honkytonk
Profil *
Chro:
Myslíš toto?
http://latrine.dgx.cz/atomicke-operace-jeste-jednou
Ale nepovedlo se mi to stáhnout. Nepoužívám Nette framework, ale doiufal jsem že kdybych našel tu třídu tak že by mi to šlo nějak upravit

Ještě mám dotaz, potřeboval bych poradit jak vygenerovat řetězec pro zápis v případě, že má obsahovat hodnoty zapisované po jednom bytu a chci tam zapsat nuly. Chr(0) zdá se nezapisuje nic. Jeden byte by měl obsahovat hodnoty od 0 až po 254 nebo od 1 až po 255, ale kdybych mohl zapsat nulu bylo by to lepší protože při následném načtení po třech bytech bych snad mohl snadno zjistit jestli ty tři byty jsou nula. To co chci udělat je načítat určitý blok po třech bytech dokud se ty tři byty nerovnají nula.
Alphard
Profil
Co třeba sprintf() se zástupným znakem %c? chr() vrací už znak.
honkytonk
Profil *
Alphard:
Mám pocit že to nefunguje:
http://pastebin.com/tw0qPHs6
když to otevřu tak tam vidím jedničky. Ale přitom prohlížeč zobrazuje na výstupu nějaké divné znaky. Nejsem si ale vědom, jak se tyto znaky dostali na výstup html kodu. Možná ten soubor jen neumí notepad přečíst? I tak si ale myslím, že printf je poměrně složitá funkce, nebyla by nějaká méně náročnější? Zatím se dívám na toto, jestli by to tím mohlo jít:
http://php.net/pack a zatím jsem na to nepřišel jestli by to šlo pomocí pack
Alphard
Profil
Tak jsem zkoušel tohle a zdá se mi to ok.

$in = sprintf('Zapis ASCII znaku: %c%c%c END', 0, 0, 0);

$hn = fopen('dat_02.txt', 'w');
fwrite($hn, $in);
fclose($hn);

Dívám se na to v PSPad Hexa editoru a je to v pořádku 0x00. Když chcete dělat podobné věci, poznámkový blok opravdu asi není ideální.
honkytonk
Profil *
u mě to zapsalo binární hodnoty 3100 ... co dělám špatně?


aha, má to být sprintf ne printf
honkytonk
Profil *
A porovnávání toho binárního bytu se prování jak?

Zkoušel jsem
$byte === 0
a !$byte

hádám že to není správné řešení :)
Jan Tvrdík
Profil
honkytonk:
Třeba:
$byte === "\x00"
honkytonk
Profil *
dík. Zase mám dotaz. Mohu stejným způsobem zapisovat do souboru, když z něj současně čtu? Tedy otevřu soubor pro čtení, použiju fseek, pak načtu byte někde z prostředku, zjistím že byte je nula, otevřu soubor ke čtení a pak ten byte přepíšu. Nebo musím nejdříve uzavřít soubor, a pak do něj teprve psát? A při načtení jiného bytu (který je zase na jiné pozici o kus dále) znovu otevřít soubor pro čtení atd.
juriad
Profil
Ano můžeš. Viz parametr mode funkce http://www.php.net/manual/en/function.fopen.php.
honkytonk
Profil *
juriad:
je tam w+ tak asi toto použít místo toho w. a rb. že bych to jako najednou otevřel jako w+ a už bych to tak nechal dokud nedokončím činnost.


vlastně w+b nebo bw+ jestli na tom pořadí nezáleží
juriad
Profil
Nejpíš chceš r+b; tedy otevři pro čtení a zápis a zachovej původní obsah souboru. To b tam musíš nechat.
Pokud nechceš zachovat původní obsah, použij w+b.
To use these flags, specify either 'b' or 't' as the last character of the mode parameter.
honkytonk
Profil *
Nedaří se mi
http://pastebin.com/xfBQTDFx
když do smyčky for ve funkci addIP přidám
echo (" <b>$i:$byte</b><br>");
tak to vypisuje hodnoty byte 9 a 4 ale v souboru 4.ip žádné takové hodnoty nevidím. Takže nefunguje ani zápis ani čtení.

include("scan_ips_class.php");
$scanIPs = new Scan_ips;
honkytonk
Profil *
žádná rada? zjišťuji že načítá ale nezapisuje:

fseek  ( $fh  , $i );
echo $i . " ";
$byte = fread($fh,1);
echo (" <b>$i:$byte</b><br>");
if ( $byte === "\x00" ){
fseek  ( $fh  , $i );
fwrite($fh,ord($arr[0]), 1);
fclose ($fh);
echo "close and exit";
break; 
}

tiskne:
93000 93000:�
close and exit
Jan Tvrdík
Profil
honkytonk:
A co by to jako mělo dělat? Např. to volání ord vypadá jako blbost, protože ti z bytu vyrobí číslo.
honkytonk
Profil *
no já zkoušel více věcí dosadit i bez toho ord. Nejsprávněji asi bude toto:
fwrite($fh,decbin($arr[0]), 1);
přečetl jsem jeden byte a protože jsem ujistil že je to nula, tak ho chci přepsat první hodnotou z pole $arr[0].


tedy první hodnotou z pole $arr . Tedy $arr[0] je první hodnota.
Jan Tvrdík
Profil
honkytonk:
Co takhle? Za předpokladu, že $arr[0] obsahuje daný byte.
fwrite($fh,$arr[0], 1);
honkytonk
Profil *
To nefungovalo. Ale $arr obsahuje defacto string number vygenerovaný pomocí explode(".",$ip); Proto asi bude lepší tam dát ten převod.


momentálně tam je číslo $arr[0]="125";
Jan Tvrdík
Profil
Tak v tom případě
fwrite($fh,chr($arr[0]), 1);
honkytonk
Profil *
ani to nic nezapíše...


zdá, se že jsem zapoměl nastavit to co psal jurid... jaj, tak už to jede


tak funguje jen to char 7D00 ty ostatní pokusy dávají 3100
Alphard
Profil
Pomocí sekvence "\x00" můžete i vytvářet řetězec. Já jsem s tím sprintf() asi úplně neodhadl vaše potřeby.

Můžete vysvětlit o co se vlastně snažíte? Nemám chuť snažit se to reverzně odhadovat a už se začínám ztrácet i v tom, kde je aktuálně. Ten kód je strašně nízkoúrovňový, je k tomu důvod?
honkytonk
Profil *
Tady je celá třída. Funguje to jen z části. Chci zapsat tři čísla v binární podobě do souboru. Řádky 95, 97, 99 mají určovat do které pozice chci zapisovat. Bohužel ale funguje jen řádek 95-96. Zapisuji tři čísla, která jsou v poli $arr.

http://pastebin.com/VHM3QeYW

Alphard:
Co znamená slovo nízkoúrovňový? Nevím co chcete říct. Už mě to taky napadlo použít to \x ale teď zas řeším něco jiného.


                        fseek($fh, $i );
                        echo "<h1>$i</h1>";
                   fwrite($fh, chr($arr[0]), 1);
                        echo "<h1>".($i+$this->rowLength)."</h1>";
                        fseek($fh, $i+$this->rowLength );
                        echo "<h1>".($i+2*$this->rowLength)."</h1>";
Alphard
Profil
Definici se přečtěte na Nižší programovací jazyk – Wikipedie, berte to s rezervou, ale ten váš kód opravu vypadá, jako byste ještě včera večer dělal v C a dneska si řekl, že zkusíte PHP. Ta „třída“ ve stylu historického PHP 4 také moc nepomáhá.

A chtěl jsem tím říct, že je možná tohle blbnutí s jednotlivými bajty zbytečné a šlo by to lépe. Proto jsem se ptal, o co se snažíte.
honkytonk
Profil *
Alphard:
Jo tak o to mi jde, aby to bylo rychlé a nenáročné. Jj, naposledy jsem psal v php 4, to je pravda, ale zase mě napsaní třídy nedělá nějak velký problém, i když je to už delší doba, takže se do toho musím zase dostat. Nejraději bych vám předvedl funkční třídu na které uvidíte o co mi jde sám.
honkytonk
Profil *
Alphard:
Udělal jsem úpravy na třídě, myslím že by už mělo být jasné o co se snažím, ale vyskytl se mi tam bug někde na řádcích 413-421 - při druhém pokusu zapsat data to vypadá jakoby se ten soubor přepsal špatně - v hexa editoru vidím 0ECD a zbytek zmizel (ale soubor přitom má 187 kb). Block 413 - 421 je jen dočasný za účelem testu bugu.

http://pastebin.com/16U7pGXk
« 1 2 »

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0