I have read a fixed length Record from the file Using php. I have given the code below.
$f = fopen('data.txt', 'rb');
while (!feof($f)) {
// read one segment of 52 bytes
if ($s = fread($f, 52)) {
// unpack the binary structure into an associative array
print_r(unpack('ieid/ieage/a20name/a20city', $s));
}
}
fclose($f);
Now i need to know How to write the Fixed Length record to the file. I searched in many web sites but still i didn't get the correct answer . How can i write the fixed Length record to the binary / text file ?
Related
I've read a part of file and now want to make sure the part is the right size. How can I do it in php?
$part = fread($file, 1024);
return some_function($part) == 1024;
I've read the examples, but a I doubt to use strlen in cause of Null-terminated string, that might be inside the binary data in $part. In this way strlen returns size from start of part and until first null-byte is presented in data.
As stated in the PHP manual, strlen returns the number of bytes in the string, not the character length.
In PHP, a null byte in a string does NOT count as the end of the string, and any null bytes are included in the length of the string.
So strlen can be used for binary data, no matter if the data is from a file or some other source.
According to PHP documentation of fread() function you may use the construction using filesize() as shown in the first example:
<?php
// get contents of a file into a string
$filename = "/usr/local/something.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
?>
Update: to find a size of the file can be used function stat() without opening or fstat() on opened file.
I am using following code to convert a binary file into an array.
$handle = fopen($file, "r");
$contents = fread($handle,filesize($file));
$array = unpack("s*", $contents);
I want to be able to read it in chunks and send multiple separate requests to process it in parallel.
For example, I want to grab first 16000 bytes, then next 16000 etc.
So I would end up with multiple sets of data to process in parallel
$content1 = first 16000 bytes
$content2 = bytes from 16000 to 32000
$content3 = bytes from 32000 to 48000
I think this is pretty simple I am just not sure how it can be done.
A simple way would be to use substr() to split out chunks until it runs out of something to process...
$start = 0;
$size = 16000;
$contents = file_get_contents($file);
while ($chunk = substr($contents, $start, $size)) {
// Process
echo ">".$chunk."<".PHP_EOL;
$start +=$size;
}
Another way would be to convert it to array to split the string into chunks, you can use str_split()
$contents = file_get_contents($file);
$chunks = str_split($contents, 16000);
file_get_contents() does all the open file/read/close in one go, the str_split() then splits it up into an array of the size chunk you want it (16000 in this case).
Not sure how much performance gain you will get by this, but that is something you will have to test for yourself.
(Also check the notes on the manual page in case you are using multi-byte encoded files).
you should use the multi thread in php
see
http://php.net/manual/en/intro.pthreads.php
and
Does PHP have threading?
Given that the OP has accepted Nigel's answer, then the question was actually how to read arbitrary chunks from a file. That can be done with a slight variation of the original code. Instead of reading the complete file contents:
fread($handle, filesize($file));
^^^^^^^^^^^^^^^
… you pass your chunk size as second argument:
$contents = fread($handle, 16000);
Prior to that, you move to the desired location:
// E.g. Read 4th chunk:
fseek($handle, 3 * 16000);
Full stuff:
$handle = fopen($file, "r");
fseek($handle, 3 * 16000);
$contents = fread($handle, 16000);
Add some error checking and you're done. These are really old functions very close to the C implementation so they should be pretty fast and require very little memory.
I need some data from a specific byte in range in a binary file.
(concatenated jpegs, don't ask...)
So I have a offset and length data from an external API.
(I would guess that those are byte positions)
What works is the following:
$fileData = file_get_contents($binaryFile);
$imageData = substr($fileData, $offset, $length);
But i would rather not load the full file into memory and therefor tried fopen:
$handle = fopen($binaryFile, 'rb');
fseek($handle, $offset);
$imageData = fgets($handle, $length);
But that doesn't work. The data chunk is no valid image data.
So i assume i got the position wrong with fopen.
Any ideas on how the positions differ in substr vs fopen?
You wrote
The data chunk is no valid image data
"image data" - but in your code you call fgets() to read that data. That's wrong, as image is binary data, not a text file, so you don't want it read it by lines (docs):
fgets — Gets line from file pointer
This means fgets() would stop reading from file once it finds what it considers line end marker, which usually means stopping earlier and reading less than $length as there's pretty low chance such byte is not in the binary sequence.
So fgets() wrong method to use and this is the main issue. Instead you should pick less smart fread() (which does not know about lines and stuff, and just reads what you told). Finally you should fclose() the handle when you done. And naturally you should always check for errors, starting from fopen():
if ($handle = fopen($binaryFile, 'rb')) {
if (fseek($handle, $offset) === 0) {
$imageData = fread($handle, $length);
if ($imageData === false) {
// error handling - failed to read the data
}
} else {
// error handling - seek failed
}
fclose($handle);
} else {
// error handling - can't open file
}
So always use right tool for the task, and if you are unsure what given method/function does, there's always not-that-bad documentation to peek.
You can use file_get_contents, too. See this simple line:
imageData = file_get_contents($binaryFile, null, null, 0, $length);
And here the documentation of file_get_contents.
I have to stress test an URL (PHP script) using Apache Benchmark. But for each request, I need a different set of data to be processed, and the URL to remain the same. So inside that PHP script I need to read a 3.000.000 lines file and pick a random one. It means that for each ab request, I need to read that file, then get a random line, then process it.
What method do you recommend?
I was thinking to somehow load that file in memory once (and be available for all requests) and then get a random line from it.
In other words, I need to read one random line from a large file without "feeling" it.
Thank you!
$fh = fopen($file, 'r');
$stats = fstat($fh);
// jump to random location within file
fseek($fh, mt_rand(0, $stats['size'] - 1));
// check where you are
$chr = fread($fh, 1);
// while you're not at a newline and not at the start of the file
while ($chr != "\n" && ftell($fh) > 0) {
// go back one character (plus an additional one you've just read)
fseek($fh, -2, SEEK_CUR);
$chr = fread($fh, 1);
}
// you're just past a newline now, go read the whole next line
$line = fgets($fh);
I need some help with this code. I am pretty sure the code is correct but I could be wrong. The problem is that the getSourceCode() isn't pulling the entire contents of the URL. It only returns a third of the data, for example: the $size variable would return 26301 and the returned data size would only be 8900. I have changed php.ini to have max file size of 100M so I don't think that is problem.
private function getSourceCode($url){
$fp = fopen($url, "r");
$size = strlen(file_get_contents($url));;
$data = fread($fp, $size);
fclose($fp);
return $data;
}
Ok, well, if you're using file_get_contents you shouldn't be using fread too.
private function getSourceCode($url){
return file_get_contents($url);
}
Short answer is that byte != 1 character in a string. You can use $data= file_get_contents($url) to get the entire file as a string.
Long answer fread is looking for the number of bytes but strlen is returning the number of characters and a character can be larger than 1 byte so you can end up not getting the entire file. Alternatively you could use filesize() to get the file length in bytes instead of strlen().