Newsgroup: it.comp.www.php
Titolo: Problemi di memoria (2)

Riguardo il precedente post...
ho cercato di utilizzare un archivio di testo. Questo: 
http://www.salvatorepaci.it/archivio.txt
e questo codice:
----------------------------------------
<?php
$fd=fopen("../archivio.txt","r");
while(!feof($fd))
 {
 $es++;
 $riga = fgets($fd,4096);
 $e[$es][0][1] = substr($riga,0,2);
 $e[$es][0][2] = substr($riga,2,2);
 $e[$es][0][3] = substr($riga,4,2);
 $e[$es][0][4] = substr($riga,6,2);
 $e[$es][0][5] = "00";
 $xxx = 6;
 for($a1 = 1; $a1 < 12; $a1 = $a1 + 1)
  {
  for($a2 = 1; $a2 < 6; $a2 = $a2 + 1)
   {
   $xxx = $xxx + 2;
   $e[$es][$a1][$a2] = substr($riga,$xxx,2) * 1;
   }
  }
 }
fclose($fd);
?>
---------------------------------------
Il problema � sempre lo stesso. Allowed memory size of 16777216 bytes 
exhausted
Preciso che un elemento di array pu� contenere un valore numerico di due 
cifre.
...
distinti saluti,
Salvatore Paci 

 cifre.
scusa ma se "valore numerico di due cifre" equivale a "numero intero da 0 a 99"
o anche "numero intero da -127 a +127" oppure "numero intero da 0 a 255" basta
UN BYTE per memorizzarlo.
Ciao,
luigi
-- 
/
+--[Luigi Rosa]--
\
The proof that IBM didn't invent the car is that it has a steering wheel
and an accelerator instead of spurs and ropes, to be compatible with a horse.
    --Jac Goudsmit

 luigi
-----------
S�, � vero.
Mi chiedo... e non � la prima volta...
se il file che apro � grande solamente
269Kb... (e lo carico in memoria una solta volta) come mai viene superato il
limite di 16Mb?
Enrico mi ha risposto:
Immagino che l'array si ingrandisca pi� di 16 mb (magari perch� prendi
un intero al posto del carattere (ergo 4 byte al posto di 1))
Ed io chiedo ancora... come faccio a non prendere 4 byte?
ciao 

 Ed io chiedo ancora... come faccio a non prendere 4 byte?
Devi impacchettare due byte in un integer.
Ragionando in esadecimale, se hai i byte 0x10 e 0xa5, li impacchetti
nell'integer 0x10a5
Ma non ti conviene usare un database?
Ciao,
luigi
-- 
/
+--[Luigi Rosa]--
\
Con un militare sai sempre dove stai, ma non con i politici,
nemmeno quelli del tuo Paese.
    --Tom Clancy, "Il cardinale del Cremlino"

 luigi
----------
Non posso usare un database perch� in giro ci sono centinaia di programmi 
che effettuano il download di archivio.txt
Ho provato anche a far leggere soltanto i record dal 4000 fino al 4215 ma mi 
d� sempre lo stesso errore.
Ciao 

Aggiornamento:
while (!feof($fp))
 {
 $x1++;
 if($x1>5000)
  {
  $x1=1;
  $x2++;
  if($x2>10)
   {
   $x2=0;
   $x3++;
   echo $x3 . "<br>";
   }
  }
 //echo ord(fread($fp, 1)), ' ';
 $arc[$x1][$x2][$x3]=ord(fread($fp, 1));
 }
ho aggiunto un echo per vedere dove si ferma l'elaborazione...
legge da [1][0][0] a [5000][10][1]
gi� dal [5000][10][2] si ferma
:((( 


http://www.salvatorepaci.it/archivio.txt
Okay. Un sistema crudele ma funzionante:
	function getarc($x1, $x2, $x3)
	{
		GLOBAL $archfd;
		if (!isset($archfd))
			if (!($archfd = fopen('../archivio.txt', 'r')))
				die('ERRORE IN ACCESSO ARCHIVIO');
		fseek($archfd, 2*($x1 + 5000*($x2 + ($x3-1)*11)),
SEEK_SET);
		return floor(fread($archfd, 2));
	}
Questo NON occupa memoria e su tutti i sistemi un minimo civili costa
quanto un accesso alla memoria (296 Kb di file di testo, de', trovami
una cache che li schifi. Forse Windows 95. E dico: forse).
Leonardo
-- 
Linten addie toorin addie,
Linten addie toorin ee,
Linten lowrin lowrin lowrin,
The barnyards of Delgaty

 }
Intanto ti ringrazio immensamente...
premesso che l'archivio � questo 
www.salvatorepaci.it/archivio.txt
e che la prima riga � la seguente:
0501194587340159501817454982204332475733622532370411202118114532268308802418420249791710525461124134861571400000000000
Premesso che i primi 8 numeri rappresentano la data (05011945 = 05/01/1945)
Nel mio vecchio codice... in ogni riga saltavo i primi 8 caratteri per cui 
$arc[1][1][1] era uguale ad 87
Adesso... sostituendo il mio codice con il tuo... pesca un numero che si 
trova alcune righe pi� sotto.
Sto cercando di adattare il codice che mi hai gentilmente fornito tu.
Per� pu� darsi che faccia prima tu...
A presto e... grazissime 

trova alcune righe pi� sotto.
Con 1-1-1 pescava 87?
Allora devi mettere:
fseek($archfd, 2*($x1-1+5000*(x2-1+(x3-1)*11) + 8);
1-1-1 = 87, 2-1-1 = 34.
...adesso devi controllare cosa ti viene con [1][2][1] e [1][1][2], per la
messa a punto finale :-)


 Leonardo
---------------
Adesso mi d� errore  perch� il numero delle parentesi aperte/chiuse non 
corrisponde.
Inoltre, nella mia ignoranza, ho provato anche a mettere ",SEEK_SET"
Domanda:
Se una riga � composta da 118 caratteri...
Perch� quel 5.000 � sempre presente nel codice?
Oggi pomeriggio mi ero avvicinato alla soluzione con:
fseek($archfd, 2*(($x1*118)-118)+8+(($x2*10)-10) + $x3 -1,SEEK_SET);
per� ancora non ne sono uscito fuori :(((
Ciao e grazie 

Perch� quel 5.000 � sempre presente nel codice?
Ach, non avevo capito che ci sono i ritorni carrello.
Dunque, ogni riga e' composta di 110+8 caratteri, ovvero una data piu' 55
numeri di due cifre.
x1 aumenta sulla riga da 1 a 5000; quando supera 5000 aumenta x2 e quando
x2 supera 11 aumenta x3.
Quindi x2 vale 5000 x1, x3 vale 55000 x1 (o 11 x2).
L'indirizzo "lineare" del punto [x1 x2 x3] quindi �
	$x1-1 + 5000*(($x2-1) + 11*($x3-1))
L'indirizzo file di questo punto va ottenuto dividendo per 55 (ogni riga,
infatti, contiene 55 punti) e moltiplicando per la lunghezza di ogni riga
per poi sommare il resto a 55, moltiplicato per due, piu' otto.
	$linear	= $x1-1 + 5000*(($x2-1) + 11*($x3-1));
	$riga	= floor($linear / 55);
	$colonna= $linear % 55;
	fseek($archfd, $riga * 120 + $colonna * 2, SEEK_SET);
"120" perche' ogni riga sono 118 caratteri piu' \r\n di ritorno carrello.
Questo programma
<?php
        function getarc($x1, $x2, $x3)
        {
                GLOBAL $archfd;
                if (!isset($archfd))
                        if (!($archfd = fopen('archivio.txt', 'r')))
                                die('Impossibile aprire archivio');
                $x1--;
                $x2--;
                $x3--;
                $linear = $x1 + 5000*($x2 + 11*$x3);
                $riga   = floor($linear / 55);
                $colonna= $linear % 55;
                fseek($archfd, $riga * 120 + $colonna * 2 + 8, SEEK_SET);
                return floor(fread($archfd, 2));
        }
        for ($x1 = 1; $x1 < 4; $x1++)
        for ($x2 = 1; $x2 < 4; $x2++)
        for ($x3 = 1; $x3 < 4; $x3++)
        printf("archivio[$x1][$x2][$x3] = " . getarc($x1,$x2,$x3) . "\n");
?>
da' questo output. Se mi compili il form, posso vedere di migliorare la
cosa :-)
archivio[1][1][1] = 87 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][1][2] =  1 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][1][3] = 74 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][2][1] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][2][2] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][2][3] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][3][1] = 62 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][3][2] = 45 [ ] va bene [ ] no, dovrebbe essere: __
archivio[1][3][3] = 37 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][1][1] = 34 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][1][2] = 31 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][1][3] = 48 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][2][1] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][2][2] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][2][3] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][3][1] = 10 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][3][2] = 28 [ ] va bene [ ] no, dovrebbe essere: __
archivio[2][3][3] = 74 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][1][1] =  1 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][1][2] = 74 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][1][3] = 90 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][2][1] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][2][2] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][2][3] =  0 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][3][1] = 47 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][3][2] = 58 [ ] va bene [ ] no, dovrebbe essere: __
archivio[3][3][3] = 24 [ ] va bene [ ] no, dovrebbe essere: __


 archivio[3][3][3] = 24 [ ] va bene [x ] no, dovrebbe essere: 43
Grazie per la pazienza 

 
<?
$dati = file_get_contents("archivio.txt");
$et = explode("\r\n",$dati);
$linee = count($et);
for($i=0; $i<$linee; $i++){
    $riga = $et[$i];
    $es = $i;
 $e[$es][0][1] = substr($riga,0,2);
 $e[$es][0][2] = substr($riga,2,2);
 $e[$es][0][3] = substr($riga,4,2);
 $e[$es][0][4] = substr($riga,6,2);
 $e[$es][0][5] = "00";
 $xxx = 6;
 for($a1 = 1; $a1 < 12; $a1 = $a1 + 1) {
  for($a2 = 1; $a2 < 6; $a2 = $a2 + 1){
   $xxx = $xxx + 2;
   $c[$es][$a1][$a2] = substr($riga,$xxx,2) * 1;
   }
  }
}
$nn = var_export($c,true);
file_put_contents("file.txt",$nn);
?>
be e' molto lento a far vedere i risultati a video per il resto cia ha
impegato uno sputo
occhio che l'array $e e diverso da $c (di fatti da 2 risutati
differenti) da il risultato che chiedi
http://it.php.net/manual/en/function.file-get-contents.php
Note: This function is binary-safe.


> archivio[3][3][3] = 24 [ ] va bene [x ] no, dovrebbe essere: 43
De', due errori, mi credevo peggio. La funzione dovrebbe essere questa
- andrebbe confrontata con valori molto pi� grandi del primo parametro
(qui 1-2-3 e basta), forse.
        function getarc($x1, $x2, $x3)
        {
                GLOBAL  $archfd;
                if (!isset($archfd))
                        if (!($archfd = fopen('archivio.txt', 'r')))
                                die('Impossibile aprire archivio');
                $x1--; $x2--; $x3--;
                $linear = ($x1*11+$x2)*5+$x3;
                $riga   = floor($linear / 55);
                $colonna= $linear % 55;
                fseek($archfd, $riga * 120 + $colonna * 2 + 8, SEEK_SET);
                return floor(fread($archfd, 2));
        }
======================
        for ($x1 = 1; $x1 < 4; $x1++)
        for ($x2 = 1; $x2 < 4; $x2++)
        for ($x3 = 1; $x3 < 4; $x3++)
                print "archivio[$x1][$x2][$x3] = " . getarc($x1,$x2,$x3) .
"\n";
Il risultato e' quello atteso.


 Leonardo
----------
Mi hai risolto un grosso problema: non ho parole.
Ciao e grazie
Un ringraziamento anche a tutti gli altri amici.
Salvatore Paci