Solved! I used an existing json file that I was using to display diagrams on the page.
I have a 2000 line text file. I want to read in the first 3000 bytes to a php variable. This works, but only at the cost of reading in the entire text file:
$little_diagrams = ('assets/diagrams.txt'); $mason = file($little_diagrams);
I tried this, but it doesn't work. Any ideas on why?
$little_diagrams = file_get_contents("assets/diagrams.txt", NULL, NULL, 0, 3000);
$mason = file($little_diagrams);
The trouble is that I have to process lines in "assets/diagrams.txt" such as:
2833|6979|Poloskov|||Nikolayev|Igor|2272|1n3rk1/3p1ppp/5q2/2p1P3/2B2P2/r2Q2P1/1b2N2P/1R3K1R|
2832|6979|Poloskov|||Nikolayev|Igor|2272|r2qk2r/1b1p1ppp/n4b2/2pN4/2B1P3/8/PP3PPP/R2QK1NR|
2831|6978|Nikolayev|Igor|2272|Buturin|Vladimir (IM)|2405|r3r1k1/1ppb1pp1/3p1n1p/2nP4/p3P3/4NP2/PPBN1KPP/R3R3|
2830|6978|Nikolayev|Igor|2272|Buturin|Vladimir (IM)|2405|r2qr1k1/1ppb1pp1/p1np1n1p/8/3PP3/4NN2/PPB2PPP/R2Q1RK1|
2829|6977|Nikolayev|Igor|2272|Tabatadze|Tamaz|2288|2rqk2r/4bp1p/p1n1b3/3pP3/Pp1P2p1/1P3p2/1B2NPPP/2RQNRK1|
2828|6976|Lutsko|Igor|2307|Nikolayev|Igor|2272|6r1/1pp2p1k/p2p3p/2bP4/2P2r2/1P4NP/P2R1P1K/5R2|
NEW CODE: (doesn't work, no diagrams are displayed at http://communitychessclub.com/ left column bottom)
$filename = "assets/diagrams.txt";
$handle = fopen($filename, "r");
$little_diagrams = fread($handle, 3000); //<<--- as per your need
fclose($handle);
$X = 5000; $line = 0;
foreach($little_diagrams as $line) {$X++; if ($X >= 5040) {break;} $token = explode("|", $line); //etc
}
<?php
$filename = "c:\\files\\yourfile.txt";
$handle = fopen($filename, "rb");
//$little_diagrams = fread($handle, filesize($filename));
$little_diagrams = fread($handle, 3000); //<<--- as per your need
fclose($handle);
?>
Try above code and read this fread function documentation
I hope this will help also see the example code Example #2 Binary fread() example
fread takes two arguments
string fread ( resource $handle , int $length )
second is length part
length bytes have been read as per documentation
fread() reads up to length bytes from the file pointer referenced by handle. Reading stops as soon as one of the following conditions is met:
UPDATED BELOW
Note:
You can use file_get_contents() to return the contents of a file as a string.
change second argument to FALSE from NULL then try hope it will work
so in my opinion correct code will be like below take a try
<?php
//however working with null also
$file_content =file_get_contents('demoTest.txt',FALSE,NULL,0,3000);
echo 'File Size: '.filesize('demoTest.txt');
echo '<br/> CONTENT HERE<br />'.$file_content;
echo '<br /><br />String Length: '.strlen($file_content);
?>
read the documentation at here for file function
I am trying to make a program where I can add things to a list, read things, and clear the list. I have the clear function working perfectly, however I can't seem to add or read more than 1 line at a time. I am using fwrite($handle, $MyString); but that replaces everything in the entire file with $MyString. To get the information from the file I am using $list = fgets($handle); and then using echo to print it. This reads the first line in the file only.
Any help?
Thanks!
Getlist code:
<?php
$myFile = "needlist.txt";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
?>
Add to the list code:
<?php
$neededlist = "needlist.txt";
$fh = fopen($neededlist, 'w');
$user_message = $_REQUEST['txtweb-message'];
$needed .= $user_message;
$needed .= "\n";
fwrite($fh, $needed);
fclose($fh);
echo "You have successfully added ", $user_message;
?>
When you write to the file are you opening your filehandle with the "a" mode option? Opening with "w" or "x" truncates it so you start with a clean file (http://php.net/fopen)
fgets(); reads only until the end of the line ( http://php.net/fgets ). To get the whole file you can try:
var $list = "";
var $line = "";
while ($line = fgets($handle)) {
$list = $list . "\n" . $line;
}
echo $list;
You want to add the "\n" because fread doesn't read the linefeeds IIRC. There're also a couple functions that might be more appropriate in this situation like file_get_contents and fread.
Fgets returns only one string. You should use it in cycle like that:
while (($buffer = fgets($handle, 4096)) !== false) {
echo $buffer;
}
I am new to php.
I am trying to count the lines on a txt document, but this always returns me 1 (despite the fact that there are a lot more lines in the file):
<?php
$file = "example.txt";
$lines = count(file($file));
print "There are $lines lines in $file";
?>
Why do you think this is?
As a side note, I am using Mac OSx.
Thanks
Try this:
$file = "example.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
$line = fgets($handle);
$linecount++;
}
fclose($handle);
echo $linecount;
From the PHP manual ( http://www.php.net/manual/en/function.file.php ):
Note: If PHP is not properly recognizing the line endings when reading files
either on or created by a Macintosh computer, enabling the auto_detect_line_endings
run-time configuration option may help resolve the problem.
That may be the cause of it. Hard to say without more information.
This will use less memory, since it doesn't load the whole file into memory:
$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
$line = fgets($handle);
$linecount++;
}
fclose($handle);
echo $linecount;
fgets loads a single line into memory (if the second argument $length is omitted it will keep reading from the stream until it reaches the end of the line, which is what we want). This is still unlikely to be as quick as using something other than PHP, if you care about wall time as well as memory usage.
The only danger with this is if any lines are particularly long (what if you encounter a 2GB file without line breaks?). In which case you're better off doing slurping it in in chunks, and counting end-of-line characters:
$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
$line = fgets($handle, 4096);
$linecount = $linecount + substr_count($line, PHP_EOL);
}
fclose($handle);
echo $linecount;
I prefer the second code if I want to know only lines in the particular file
I have an issue with writing and reading to text file.
I have to first write from a text file to another text file some values which I need to read again. Below are the code snippets:
Write to text file:
$fp = #fopen ("text1.txt", "r");
$fh = #fopen("text2.txt", 'a+');
if ($fp) {
//for each line in file
while(!feof($fp)) {
//push lines into array
$thisline = fgets($fp);
$thisline1 = trim($thisline);
$stringData = $thisline1. "\r\n";
fwrite($fh, $stringData);
fwrite($fh, "test");
}
}
fclose($fp);
fclose($fh);
Read from the written textfile
$page = join("",file("text2.txt"));
$kw = explode("\n", $page);
for($i=0;$i<count($kw);$i++){
echo rtrim($kw[$i]);
}
But, if I am not mistaken due to the "/r/n" I used to insert the newline, when I am reading back, there are issues and I need to pass the read values from only the even lines to a function to perform other operations.
How do I resolve this issue? Basically, I need to write certain values to a textfile and then read only the values from the even lines.
I'm not sure whether you have issues with the even line numbers or with reading the file back in.
Here is the solution for the even line numbers.
$page = join("",file("text2.txt"));
$kw = explode("\n", $page);
for($i=0;$i<count($kw);$i++){
$myValue = rtrim($kw[$i]);
if(i % 2 == 0)
{
echo $myValue;
}
}
I have a script which, each time is called, gets the first line of a file. Each line is known to be exactly of the same length (32 alphanumeric chars) and terminates with "\r\n".
After getting the first line, the script removes it.
This is done in this way:
$contents = file_get_contents($file));
$first_line = substr($contents, 0, 32);
file_put_contents($file, substr($contents, 32 + 2)); //+2 because we remove also the \r\n
Obviously it works, but I was wondering whether there is a smarter (or more efficient) way to do this?
In my simple solution I basically read and rewrite the entire file just to take and remove the first line.
I came up with this idea yesterday:
function read_and_delete_first_line($filename) {
$file = file($filename);
$output = $file[0];
unset($file[0]);
file_put_contents($filename, $file);
return $output;
}
There is no more efficient way to do this other than rewriting the file.
No need to create a second temporary file, nor put the whole file in memory:
if ($handle = fopen("file", "c+")) { // open the file in reading and editing mode
if (flock($handle, LOCK_EX)) { // lock the file, so no one can read or edit this file
while (($line = fgets($handle, 4096)) !== FALSE) {
if (!isset($write_position)) { // move the line to previous position, except the first line
$write_position = 0;
} else {
$read_position = ftell($handle); // get actual line
fseek($handle, $write_position); // move to previous position
fputs($handle, $line); // put actual line in previous position
fseek($handle, $read_position); // return to actual position
$write_position += strlen($line); // set write position to the next loop
}
}
fflush($handle); // write any pending change to file
ftruncate($handle, $write_position); // drop the repeated last line
flock($handle, LOCK_UN); // unlock the file
}
fclose($handle);
}
This will shift the first line of a file, you dont need to load the entire file in memory like you do using the 'file' function. Maybe for small files is a bit more slow than with 'file' (maybe but i bet is not) but is able to manage largest files without problems.
$firstline = false;
if($handle = fopen($logFile,'c+')){
if(!flock($handle,LOCK_EX)){fclose($handle);}
$offset = 0;
$len = filesize($logFile);
while(($line = fgets($handle,4096)) !== false){
if(!$firstline){$firstline = $line;$offset = strlen($firstline);continue;}
$pos = ftell($handle);
fseek($handle,$pos-strlen($line)-$offset);
fputs($handle,$line);
fseek($handle,$pos);
}
fflush($handle);
ftruncate($handle,($len-$offset));
flock($handle,LOCK_UN);
fclose($handle);
}
you can iterate the file , instead of putting them all in memory
$handle = fopen("file", "r");
$first = fgets($handle,2048); #get first line.
$outfile="temp";
$o = fopen($outfile,"w");
while (!feof($handle)) {
$buffer = fgets($handle,2048);
fwrite($o,$buffer);
}
fclose($handle);
fclose($o);
rename($outfile,$file);
I wouldn't usually recommend opening up a shell for this sort of thing, but if you're doing this infrequently on really large files, there's probably something to be said for:
$lines = `wc -l myfile` - 1;
`tail -n $lines myfile > newfile`;
It's simple, and it doesn't involve reading the whole file into memory.
I wouldn't recommend this for small files, or extremely frequent use though. The overhead's too high.
You could store positional info into the file itself. For example, the first 8 bytes of the file could store an integer. This integer is the byte offset of the first real line in the file.
So, you never delete lines anymore. Instead, deleting a line means altering the start position. fseek() to it and then read lines as normal.
The file will grow big eventually. You could periodically clean up the orphaned lines to reduce the file size.
But seriously, just use a database and don't do stuff like this.
Here's one way:
$contents = file($file, FILE_IGNORE_NEW_LINES);
$first_line = array_shift($contents);
file_put_contents($file, implode("\r\n", $contents));
There's countless other ways to do that also, but all the methods would involve separating the first line somehow and saving the rest. You cannot avoid rewriting the whole file. An alternative take:
list($first_line, $contents) = explode("\r\n", file_get_contents($file), 2);
file_put_contents($file, implode("\r\n", $contents));
My problem was large files. I just needed to edit, or remove the first line. This was a solution I used. Didn't require to load the complete file in a variable. Currently echos, but you could always save the contents.
$fh = fopen($local_file, 'rb');
echo "add\tfirst\tline\n"; // add your new first line.
fgets($fh); // moves the file pointer to the next line.
echo stream_get_contents($fh); // flushes the remaining file.
fclose($fh);
I think this is best for any file size
$myfile = fopen("yourfile.txt", "r") or die("Unable to open file!");
$ch=1;
while(!feof($myfile)) {
$dataline= fgets($myfile) . "<br>";
if($ch == 2){
echo str_replace(' ', ' ', $dataline)."\n";
}
$ch = 2;
}
fclose($myfile);
The solutions here didn't work performantly for me.
My solution grabs the last line (not the first line, in my case it was not relevant to get the first or last line) from the file and removes that from that file.
This is very quickly even with very large files (>150000000 lines).
function file_pop($file)
{
if ($fp = #fopen($file, "c+")) {
if (!flock($fp, LOCK_EX)) {
fclose($fp);
}
$pos = -1;
$found = 0;
while ($found < 2) {
if (fseek($fp, $pos--, SEEK_END) < 0) { // can not seek to position
rewind($fp); // rewind to the beginnung of the file
break;
};
if (ord(fgetc($fp)) == 10) { // newline
$found++;
}
}
$lastpos = ftell($fp); // get current position of file
$lastline = fgets($fp); // get current line
ftruncate($fp, $lastpos); // truncate file to last position
flock($fp, LOCK_UN); // unlock
fclose($fp); // close the file
return trim($lastline);
}
}
You could use file() method.
Gets the first line
$content = file('myfile.txt');
echo $content[0];