I want to read file without last x bytes in php, exactly like this:
$size = filesize($filename) - $x;
$handle = fopen($filename, "rb");
$contents = fread($handle, $size);
fclose($handle);
In my application, I will use this code a lot.
This works, but is it possible to do this more briefly and flexible, instead of using (filesize, fopen, fclose) each time?
Can file_get_contents() help? If so how do I use it?
For example (the very simple solution)
$contents = substr(file_get_contents($filename), 0, -$x);
Just remove the last bytes/characters.
It works with file_get_contents():
$contents = file_get_contents($filename, false, null, 0, filesize($filename) - $x);
Related
How can I have php return just some bytes of a file? Like, it I wanted to load byte 7 through 15 into a string, without reading any other part of the file? Its important that I don't need to load all of the file into memory, as the file could be quite large.
Could use file_get_contents() using the offset and maxlen parameters.
$data = file_get_contents('somefile.txt', false, NULL, 6, 8);
Use fseek() and fread()
$fp = fopen('somefile.txt', 'r');
// move to the 7th byte
fseek($fp, 7);
$data = fread($fp, 8); // read 8 bytes from byte 7
fclose($fp);
Using Pear:
<?php
require_once 'File.php';
//read and output first 15 bytes of file myFile
echo File::read("/path/to/myFile", 15);
?>
Or:
<?php
// get contents of a file into a string
$filename = "/path/to/myFile";
$handle = fopen($filename, "r");
$contents = fread($handle, 15);
fclose($handle);
?>
Either method you can use byte 7-15 to do what you want. I don't think you can go after certain bytes without starting from the beginning of the file.
I have got a large file in PHP of which I would like to replace the first 512 bytes with some other 512 bytes. Is there any PHP function that helps me with that?
If you want to optionally create a file and read and write to it (without truncating it), you need to open the file with the fopen() function in 'c+' mode:
$handle = fopen($filename, 'c+');
PHP then has the stream_get_contents() function which allows to read a chunk of bytes with a specific length (and from a specific offset in the file) into a string variable:
$buffer = stream_get_contents($handle, $length = 512, $offset = 0);
However, there is no stream_put_contents() function to write the string buffer back to the stream at a specific position/offset. A related function is file_put_contents() but it does not allow to write to a file-handle resource at a specific offset. But there is fseek() and fwrite() to do that:
$bytes_written = false;
if (0 === fseek($handle, $offset)) {
$bytes_written = fwrite($handle, $buffer, $length);
}
Here is the full picture:
$handle = fopen($filename, 'c+');
$buffer = stream_get_contents($handle, $length = 512, $offset = 0);
// ... change $buffer ...
$bytes_written = false;
if (0 === fseek($handle, $offset)) {
$bytes_written = fwrite($handle, $buffer, $length);
}
fclose($handle);
If the length of $buffer is not fixed this will not properly work. In that case it's better to work with two files and to use stream_copy_to_stream() as outlined in How to update csv column names with database table header or if the file is not large it is also possible to do that in memory:
$buffer = file_get_contents($filename);
// ... change $buffer ...
file_put_contents($filename, $buffer);
Im trying to extract the values between eng_tid
and eng_data for http://fdguirhgeruih.x10.mx/html.txt and I keep getting T string errors.
why do I keep getting errors
<? php
//First, open the file. Change your filename
$file = "http://fdguirhgeruih.x10.mx/html.txt";
$word1='tid';
$word2='data';
$handle = fopen($file, "r");
$contents = fread($handle, filesize($file));
fclose($handle);
$between=substr($contents, strpos($contents, $word1), strpos($contents, $word2) - strpos($contents, $word1));
echo $between;
?>
UPDATE after seeing error messages...
Instead of fread() and attempting to use the size in bytes of your target file, you may simply use file_get_contents() to retrieve the remote file. Your error is because PHP wants to read the filesize of the file as though it is local, but it is a remote file over HTTP. filesize() reports 0 and an error. Instead do
// Don't do this...
//$handle = fopen($file, "r");
//$contents = fread($handle, filesize($file));
//fclose($handle);
// Instead do this...
$contents = file_get_contents($file);
How can I have php return just some bytes of a file? Like, it I wanted to load byte 7 through 15 into a string, without reading any other part of the file? Its important that I don't need to load all of the file into memory, as the file could be quite large.
Could use file_get_contents() using the offset and maxlen parameters.
$data = file_get_contents('somefile.txt', false, NULL, 6, 8);
Use fseek() and fread()
$fp = fopen('somefile.txt', 'r');
// move to the 7th byte
fseek($fp, 7);
$data = fread($fp, 8); // read 8 bytes from byte 7
fclose($fp);
Using Pear:
<?php
require_once 'File.php';
//read and output first 15 bytes of file myFile
echo File::read("/path/to/myFile", 15);
?>
Or:
<?php
// get contents of a file into a string
$filename = "/path/to/myFile";
$handle = fopen($filename, "r");
$contents = fread($handle, 15);
fclose($handle);
?>
Either method you can use byte 7-15 to do what you want. I don't think you can go after certain bytes without starting from the beginning of the file.
I'm receiving files (images) uploaded with Ajax into my PHP script and have got it to work using this:
$input = fopen("php://input", "r");
file_put_contents('image.jpg', $input);
Obviously I will sanitize input before this operation.
One thing I wanted to check was the file size prior to creating the new file, as follows:
$input = fopen("php://input", "r");
$temp = tmpfile();
$realsize = stream_copy_to_stream($input, $temp);
if ($realsize === $_SERVER["CONTENT_LENGTH"]) {
file_put_contents('image.jpg', $temp);
}
And that doesn't work. The file is created, but it has a size of 0 bytes, so the content isn't being put into the file. I'm not awfully familiar with using streams, but I don't see why that shouldn't work, so I'm turning to you for help. Thanks in advance!
The solution was deceptively simple:
$input = fopen("php://input", "r");
file_put_contents($path, $input);
You are using file resources as if they were strings. Instead you could again use stream_copy_to_stream:
stream_copy_to_stream($temp, fopen('image.jpg', 'w'));