een paar regels van .txt bestand lezen

Status
Niet open voor verdere reacties.

carlo boy7

Gebruiker
Lid geworden
28 feb 2009
Berichten
156
Hallo, ik heb een groot .txt bestand, deze bevat ruim 2000 regels.
Omdat ik de gegevens van het .txt bestand met inhoud van een database wil vergelijken gebruik ik een script die het .txt bestand uitleest.

Alleen als ik dit doe, wordt mijn website sloom, en is niet meer te gebruiken totdat deze 'update' tijd klaar is.

Daarom wil ik vragen, is het mogelijk om van een .txt bestand de eerste 100 regels te lezen, en dan een kwartier later (cronjob) de regels van 100-200 te lezen enz.

Alvast heel bedankt

PS. De getallen zijn geschat, ik weet natuurlijk niet hoeveel regels er in het .txt bestand staan
 
Wat voor script gebruik jij dan om dat tekstbestand uit te lezen? Als je website hangt, dan mag er wel iets gigantisch fout gaan op dat moment... PHP moet namelijk geen enkele moeite hebben met 200 regels code.
 
Het is even een globaal gekozen, er zitten 338,243 records in datebase. Dat zijn dus 338,243 regels in dat .txt bestand
 
Haha, oke, dat zijn er dus iets meer dan 2000 stuks. Aantal vraagjes:

- Hoe vaak doe je die controle dan?
- Is het niet een optie om dat eenmalig 's nachts rond 4 uur te doen?
- Ik weet niet waar het voor is, maar is die controle niet op een andere manier te regelen?
 
- Ik werk via cronjob en doe het elk uur wordt de controle gedaan
- Nee, de website moet goede inhoud weergeven; wat up-to-date is. Dus ik moet het om het uur laten updaten
- Ik heb al een "map database" proberen te maken :p. Maar MySQL is toch het beste

EDIT: Het bestand bevind zich buiten de server.
Ik heb toestemming gekregen van de eigenaar om het te rippen

Dit heb ik al geprobeert
PHP:
class dorp
{
	private $_file;
	public function __construct( $start,$end, $link)
	{
		$this->make_file($start,$end,$link);
	}
	private function make_file($start,$end,$link)
	{
		$file = fopen(date("d/m/Y").'_d.txt','w'); // Bestand openen of aanmaken zie bovenstaande informatie..
		fwrite($file, file($link.'/map/village.txt')); // Tekst erin schrijven		
		fclose($file);
		$this->_file = file_get_contents(date("d/m/Y").'_d.txt',NULL,NULL,$start,$end); //dit moet aangepast worden
	}
}
$dorp = new dorp(1,5,'Website aders');
 
Laatst bewerkt:
Oke... En waar krijg jij dat txt bestand van dan? Enige oplossing zie ik door het anders aan te passen aan de kant waar dat txt bestand word gegenereerd. Maar dat is niet altijd mogelijk, haha

Ik heb er zelf geen ervaring mee, met dit soort grote dingen, dus mijn ideeën houden hier nu even op. Misschien dat iemand anders je hier wel verder mee kan helpen.


Kun je een stukje code laten zien hoe je het bestand nu inleest en vergelijkt met de database?
 
@SumBeam je was me voor, heb mijn vorige post bijgewerkt. Dan zijn je vragen duidelijk :)
 
Hmm, oke, haha. Je hebt je bericht net gewijzigd toen ik gepost had :)

Maar oke, duidelijk. Je maakt hier een nieuw bestand aan zie ik, ter vervanging van de database?

Even voor de duidelijkheid:
Je ript dat bestand van een andere server af, en je wilt de data die in dat bestand staat, in je eigen database hebben. Dit doe je elk uur, alleen elk uur wil je alleen de 'nieuwe' of 'gewijzigde' data in de database hebben gewijzigd?


Kun je een voorbeeld geven hoe dat tekstbestand eruit ziet? Enkele regels, zodat de structuur me duidelijk is.
 
Je hebt hem, je moet hem rippen naar je website, anders werkt dat "file_get_contents" niet... file_get_contents pakt dan de regels tussen $start en $end.

Alleen dat rippen gaat ook langzaam, mijn god.... Weer hele website onbruikbaar :(

Code:
1,Bonusdorp,484,472,0,208,7
2,Barbarendorp,482,570,0,174,0
3,Bonusdorp,502,440,0,150,5
4,Bonusdorp,572,514,0,202,9
5,dutch+001,439,552,567844,378,0
6,D+and+M%3A+Playtime%21,564,517,523655,483,0
7,%7C%7C001%7C%7C,504,444,1831884,437,0
8,N0ChanC3s+dorp,516,447,1555596,517,0
9,LoveYa.,456,533,922334,569,0
10,Barbarendorp,466,504,0,77,0
11,Dynamite...,476,483,1831890,408,0
12,Barbarendorp,485,458,0,174,0
13,Barbarendorp,432,458,0,135,0
14,Bonusdorp,500,541,0,187,1
15,Barbarendorp,573,475,0,235,0
16,Barbarendorp,489,485,0,163,0
17,Barbarendorp,455,543,0,222,0
18,%5B001%5D+Travian01,492,560,556810,753,0
19,Barbarendorp,524,463,0,170,0
20,Reborn+7.0,552,473,1813172,345,0
21,Bonusdorp,513,514,0,155,9
22,Never+Walk+Together,462,497,1567100,252,0
23,B.arca+%5B001%5D,446,445,781787,318,0
24,stephan596s+dorp,533,503,435433,188,0
25,Barbarendorp,430,491,0,177,0
26,Barbarendorp,493,486,0,156,0
27,Barbarendorp,460,548,0,342,0
28,Bonusdorp,454,537,0,141,8
29,Ik+Lust+Je+Rauw+-+RAAAAAWR%21,482,556,1820782,1381,0
30,Barbarendorp,556,502,0,132,0
31,Barbarendorp,523,484,0,279,0
32,Bonusdorp,509,480,0,169,9
33,%5B01%5D-%5BVervunhive%5D,487,521,340802,618,0
34,Only+One%3F,549,498,1827758,856,0
35,Bonusdorp,504,558,0,166,7
36,FTW,499,455,741241,430,0
37,Gold,511,568,790920,490,0
38,Bonusdorp,502,554,0,185,1
39,gvcgjfcgfs+dorp,509,517,1701741,250,0
40,Barbarendorp,441,547,0,177,0
tribalwars
 
Je kunt stukjes van een file lezen mbv de functies fopen en fread.

PHP:
$file = fopen ( "file.txt" );
$eerste_100_tekens = fread( $file, 100 );
$tweede_100_tekens = fread( $file, 100 );

Verder kun je springen naar een positie in de file met fseek():

PHP:
$file = fopen( "file.txt" );
fseek( $file, 200 ); // spring naar het 200ste teken in de file

Je zult wel zelf even moeten zoeken naar newlines want je laadt hiermee echt losse karakters in, maar als je bijv. 5000 tekens inlaad, zoekt naar de laatste newline, en vervolgens die regels behandelt en opslaat waar je gebleven bent, dan kun je wel doen wat jij wilt, met een cronjob steeds een stukje van de file inlezen.

Is wel wat lastiger dan gewoon file() gebruiken helaas ;)
 
ja hier komt ie1

meer dan je wil maar je kan ze gewoon gebruiken

Je moet weten dat je wait() zal nodig heben om je script 1uur in wait te plaatsen maar dan moet je ook rekeninghouden met maximum executiontime zie php.ini of je hosting om raad vragen en melden dat je een wait wil gebruiken.
PHP:
<?PHP
 /**
 * @author Lieven Roegiers
 * @copyright 2007 refactor 2009
 * @CMS autosite
 * opensource http://code.google.com/p/autosite/
 */
if (!function_exists('csv_plus')){//include_once its when it is include in the php lib
class csv_plus implements tosave{
	private	$Delimiter=',';
	private $maxfilesize=1000;
	private $filelocation;
    private $minlivetime =0;
	private $file;
	private $errornr;
	/** 
	 * @param mixed $pathname
	 * @param mixed $filelocation
	 * @param integer $lifetime
	 * @return
	 */
	public function __construct($pathname,$filelocation,$lifetime = 0){
		$this->filelocation=$pathname.$filelocation;
		$this->minlivetime = $lifetime;//(1 * 1 * 60 * 60);
	}
	/**
	 * @param string $mode
	 * @return
	 */
	private function open($mode='a+'){
		return($this->is_readytouse()&& $this->file = fopen($this->filelocation,$mode)); //File!found E53 
	}
	/**
	 * @param mixed $arrData
	 * @param bool $del_oldlines
	 * @return
	 */
	function save_line($arrData,$del_oldlines=true){
		if ($del_oldlines){
			$this->del_oldlines();
		}
		$timestamp = ($this->minlivetime>0)?(time()+$this->minlivetime).$this->Delimiter:"";
		$datastring =" ".$timestamp.implode($this->Delimiter,$arrData);//space on the front is for search
		$datastring = $this->Aln2br($datastring)."\n";
		return ($this->open()&& fputs($this->file, $datastring));
	}
	/**
	 * @return bool
	 */
    private function Aln2br($txt){
        return strtr($txt, array("\r\n" => '<br/>', "\r" => '<br/>', "\n" => '<br/>'));
    }
    private function Abr2ln($txt){
        return strtr($txt, array("<br />" => "\n", "<br/>" => "\n"));
    }
	public function is_readytouse(){
		return(isset($this->filelocation)&& is_file($this->filelocation));
	}
	/**
	 * @param mixed $source fname
	 * @param string $destprefix
	 * @return bool
	 */
	private function bakup($source,$destprefix=".BAK"){
		return (is_file($source) && (filesize($source)>0)&& !copy($source, $source.$destprefix));
	}
    /**
	 * @return void
	 */
 	private function add($source,$destprefix=".BAK"){
		return (is_file($source) && (filesize($source)>0)&& !copy($source, $source.$destprefix));
	}
    /**
	 * @return void
	 */
	private function del_oldlines(){
		if ($this->is_readytouse()&& filesize($this->filelocation)>$this->maxfilesize){
			if ($this->bakup($this->filelocation)){//rename($path.$file, $path.$bakfile);
				unlink ($this->filelocation);
			}
			$lines = file($this->filelocation.".BAK");
			if (!$this->open()) {
				foreach ($lines as $line_num => $line){
					$kkey=explode(',', $line);
					if((time() > $kkey[0])){//releastijd
					}elseif(fputs($file,$line)){//infileplaatsen
					}else {//echo "error write bakup";
					}
				}		
			}
		}	
	}
	/**
	 * @param mixed $Fname
	 * @return
	 */
	function HTML_listvieuw($Fname){
		$row = 1;
		$fp = fopen ($fname,"r");
		while ($data = fgetcsv($Fname,1000,",")) {
		    $num = count ($data);
		    print "<p> $num velden in regel $row: <br>\n";
		    $row++;
		    for ($c=0; $c < $num; $c++) {
		        print $data[$c] . "<br>\n";
		    }
		}	
	}
	/*function HTML_table($Fname){
		$row = 1;
		$fp = fopen ($fname,"r");
		while ($data = fgetcsv($Fname,1000,",")) {
		    $num = count ($data);
		    print "<p> $num velden in regel $row: <br>\n";
		    $row++;
		    for ($c=0; $c < $num; $c++) {
		        print $data[$c] . "<br>\n";
		    }
		}	
	}*/
	/**
	 * @param mixed $findstring
	 * @param integer $resul
	 * @return string line
	 */
	function find_line($findstring,$resul=1){
		if ($this->open()){
			while (!feof($this->file))
	    		{$line = fgetcsv($this->file,1024,",");
	    			if(is_array ($line)){
						if (!$pos = array_search($findstring,$line )){ 
	     				//print_r($line); //niet gekozen items	
	     				}else{
	     					return  $line ;
	     					exit;	
						}
	     			}else{
						//fun_error(381);//Invalid array
					}
	 		$line=""; 
			}
		}
	}
    	/**
	 * @param mixed $findstring
	 * @param integer $resul
	 * @return string line
	 */
	private function pos_line($findstring,$resul=1){
		if ($this->open()){
			while (!feof($this->file))
	    		{$line = fgetcsv($this->file,1024,",");
	    			if(is_array ($line)){
						if (!$pos = array_search($findstring,$line )){ 
	     				//print_r($line); //niet gekozen items	
	     				}else{
	     					return  $line ;
	     					exit;	
						}
	     			}else{
						//fun_error(381);//Invalid array
					}
	 		$line=""; 
			}
		}
	}
	/**
	 * @return
	 */
	function __destruct(){
		//fclose ($this->file);
	}	 	
}
}
?>
 
Ik dacht al dat je dat spel bedoelde, speel ik zelf namelijk ook. Misschien is dit een interessante forum post: Klik

En dan met name dit stukje:

PHP:
   $file="database.txt";
   //DÖRFER 
    query("TRUNCATE TABLE `data_towns`"); 
    $lines = gzfile('http://de28.die-staemme.de/map/village.txt.gz'); 
    if(!is_array($lines)) die("Datei konnte nicht geöffnet werden"); 
    $fp=fopen($file, 'w'); 
    foreach($lines as $line){ 
        fwrite($fp, $line); 
    } 
    $sql=query("LOAD DATA LOCAL INFILE '$file' INTO TABLE `data_towns` FIELDS TERMINATED BY ',' (`town_id`, `name`, `x`, `y`, `user`, `points`, `rank`)"); 
    fwrite($fp, ""); 
    fclose($fp); 
    unset($lines);

MySQL Load Data


Ik weet niet of je precies of je dit zoekt en ik heb ook geen idee hoe snel de mysql server zoiets kan afhandelen... Zal zelf ook eens even testen :)

EDIT:

Zelf even geprutst, ik heb er dit van weten te maken:

PHP:
// File
$file = "file.txt";
ob_start(); 
// Read the .txt.gz file
readgzfile('http://nl21.tribalwars.nl/map/village.txt.gz'); 
$contents=ob_get_clean(); 
// Save the content from the file to your $file
file_put_contents($file, $contents);

// Connect
mysql_connect("localhost","x","x");
// Select DB
mysql_select_db("tribal");

// Truncate the table
mysql_query("TRUNCATE TABLE `data_towns`");
// Insert the data into the table
mysql_query("LOAD DATA LOCAL INFILE '$file' INTO TABLE `data_towns` FIELDS TERMINATED BY ',' (`town_id`, `name`, `x`, `y`, `user`, `points`, `rank`)") or die(mysql_error());


Dit doet 3,6 sec er bij mij over om in te laden, als ik een file pak van bv wereld 1 (350.000 regels) ongeveer 30 seconden. Enige waar je voor moet uitkijken is:

[SQL]LOAD DATA LOCAL INFILE '$file' INTO TABLE[/SQL]

MySQL wil graag een harde verwijzing naar het bestand toe i.p.v. $file, zo moest ik er: E:/xampp/htdocs/file.txt neerzetten zodat het zou werken. Dit is dan wel een Windows machine, ik weet niet precies hoe dit werkt op unix variant. Maar er is wel een kans dat dit niet gaat werken, aangezien de beheerders van de host, LOAD DATA kunnen uitzetten
 
Laatst bewerkt:
Ik dacht al dat je dat spel bedoelde, speel ik zelf namelijk ook. Misschien is dit een interessante forum post: Klik

En dan met name dit stukje:

PHP:
   $file="database.txt";
   //DÖRFER 
    query("TRUNCATE TABLE `data_towns`"); 
    $lines = gzfile('http://de28.die-staemme.de/map/village.txt.gz'); 
    if(!is_array($lines)) die("Datei konnte nicht geöffnet werden"); 
    $fp=fopen($file, 'w'); 
    foreach($lines as $line){ 
        fwrite($fp, $line); 
    } 
    $sql=query("LOAD DATA LOCAL INFILE '$file' INTO TABLE `data_towns` FIELDS TERMINATED BY ',' (`town_id`, `name`, `x`, `y`, `user`, `points`, `rank`)"); 
    fwrite($fp, ""); 
    fclose($fp); 
    unset($lines);

MySQL Load Data


Ik weet niet of je precies of je dit zoekt en ik heb ook geen idee hoe snel de mysql server zoiets kan afhandelen... Zal zelf ook eens even testen :)

EDIT:

Zelf even geprutst, ik heb er dit van weten te maken:

PHP:
// File
$file = "file.txt";
ob_start(); 
// Read the .txt.gz file
readgzfile('http://nl21.tribalwars.nl/map/village.txt.gz'); 
$contents=ob_get_clean(); 
// Save the content from the file to your $file
file_put_contents($file, $contents);

// Connect
mysql_connect("localhost","x","x");
// Select DB
mysql_select_db("tribal");

// Truncate the table
mysql_query("TRUNCATE TABLE `data_towns`");
// Insert the data into the table
mysql_query("LOAD DATA LOCAL INFILE '$file' INTO TABLE `data_towns` FIELDS TERMINATED BY ',' (`town_id`, `name`, `x`, `y`, `user`, `points`, `rank`)") or die(mysql_error());


Dit doet 3,6 sec er bij mij over om in te laden, als ik een file pak van bv wereld 1 (350.000 regels) ongeveer 30 seconden. Enige waar je voor moet uitkijken is:

[SQL]LOAD DATA LOCAL INFILE '$file' INTO TABLE[/SQL]

MySQL wil graag een harde verwijzing naar het bestand toe i.p.v. $file, zo moest ik er: E:/xampp/htdocs/file.txt neerzetten zodat het zou werken. Dit is dan wel een Windows machine, ik weet niet precies hoe dit werkt op unix variant. Maar er is wel een kans dat dit niet gaat werken, aangezien de beheerders van de host, LOAD DATA kunnen uitzetten


Bedankt! Ben best ver met mijn website, maar boste op het updaten. Ik probeer in 2011 mijn site te lazeren. :)

@kenikavanbis
Die classe lijkt me wel makkelijk, bedankt

@Frats
Bedankt voor de uitleg, ik weet een beetje hoe ik het ga aanpakken:
PHP:
$file = file ( "http://nl21.tribalwars.nl/map/village.txt" );
$start = (integer) NULL;
$tekens = (integer) NULL;
foreach($file as $lines)
{
	$tekens = $tekens+ strlen($lines); //de tekens van de regel tellen
	$start++; //de regels tellen
	if($start <101) //kijken als er 100 om zijn
	{
		//Behandel de informatie
	}
	else
	{
		break; //stop de foreach	
	}	
}
echo $tekens; //dit zijn de totale tekens
EDIT:
Alleen voor het uitlezen van het bestand van tribalwars krijg ik deze error:
Fatal error: Maximum execution time of 60 seconds exceeded in C:\xampp\htdocs\tribalwars\cronjobs\dorp\dorp.class.php on line 20
Grappig, als dit alleen de code is:
PHP:
$file = file ( "http://nl21.tribalwars.nl/map/village.txt" );

Maar het 'langzaam' probleem is opgelost, bedankt!
 
Laatst bewerkt:
Das heel logisch. file() opent de hele file voor lezen... dat betekent dat je in een keer een array met 200.000 rijen aangemaakt krijgt. Dat duurt heel lang.

Het hele punt van mijn code was juist het niet gebruiken van file() zodat je alleen stukjes van de file bekijkt.
 
Ik gebruik bijna altijd die "file" functie, doe het bijna onbewust typen..

PHP:
//$end = 100;
//$start = 1 ;
		$this->_tabel = date("d/m/Y").'_d';
		$this->_end = $end;
		$name = str_replace('/','+',$this->_tabel);
		$file = fopen( 'data/'.$name.'_d.backup.txt','r' ); //opend de file waar alle data in zat
		fseek( $file, $start ); //jump naar het teken

		$data = fread($file,filesize('data/'.$name.'_d.backup.txt'));
		$this->_array = explode("\n",$data); //breek het af in array's
		$this->checkfile(); //dan updaten
Deze wel goedgekeurd? :p
 
Nee, nu lees je nog steeds de hele file in met fread ;)
 
Ongeveer zoals ik zei. Als je begint, dan pak je bijv. de eerste 5000 tekens van de file. Vervolgens zoek je naar de laatste newline in die set, en dan knip je alles wat daarna komt weg. Dat is namelijk een incompleet record en dat heb je niet nodig.

Vervolgens behandel je alles wat er nog overblijft in die string (je zult het zelf in een array moeten stoppen met explode())

Als je dat gedaan hebt, dan meet je hoe lang de string was die je ophaalde, en dat getal sla je ergens op (in een filetje of in je database ofzo)

En als je dan de tweede keer komt, dan haal je dat getal weer op. Vervolgens begin je te lezen vanaf die locatie, en pak je weer 5000 tekens. Dan knip je weer alles na de laatste newline weg, behandel je dat stuk, en vervolgens tel je de lengte van dat stuk op bij het vorige getal dat je opgeslagen had.

En dan de derde keer, doe je weer hetzelfde als bij de tweede keer. Je haalt het getal op, je leest vanaf dat punt 5000 tekens, die behandel je, je meet de lengte en die tel je bij het vorige getal op.
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan