Самый быстрый способ чтения содержимого файла
Хорошо, я ищу самый быстрый способ прочитать все содержимое файла через php с файловым каналом на сервере, также эти файлы могут быть огромными. Поэтому очень важно, чтобы он ТОЛЬКО ПРОЧИТАЛ к нему как можно быстрее.
Читает ли это по строчке быстрее, чем чтение всего содержимого? Хотя, я помню, что читал об этом, что чтение всего содержимого может привести к ошибкам для огромных файлов. Это правда?
Ответы
Ответ 1
Если вы хотите загрузить полное содержимое файла в переменную PHP, самым простым (и, возможно, самым быстрым) способом будет file_get_contents
.
Но, если вы работаете с большими файлами, загрузка всего файла в память может быть не такой хорошей идеей: вы, вероятно, закончите с memory_limit
, так как PHP не позволит вашему script использовать больше, чем (обычно) пару мегабайт памяти.
Таким образом, даже если это не самое быстрое решение, чтение файла по строкам ( fopen
+ fgets
+ fclose
), и работать с этими линиями "на лету", не загружая весь файл в память, может быть необходимо...
Ответ 2
file_get_contents()
- наиболее оптимизированный способ чтения файлов на PHP, однако - поскольку вы читаете файлы в памяти , вы всегда ограничены объемом доступной памяти.
Вы можете выпустить ini_set('memory_limit', -1)
, если у вас есть права, но вы все равно будете ограничены объемом доступной памяти в вашей системе, что является общим для всех языков программирования.
Единственное решение - прочитать файл в кусках, для этого вы можете использовать file_get_contents()
с четвертым и пятым аргументами ($offset
и $maxlen
- указанными в байтах):
string file_get_contents(string $filename[, bool $use_include_path = false[, resource $context[, int $offset = -1[, int $maxlen = -1]]]])
Вот пример, когда я использую этот метод для работы с большими файлами загрузки:
public function Download($path, $speed = null)
{
if (is_file($path) === true)
{
set_time_limit(0);
while (ob_get_level() > 0)
{
ob_end_clean();
}
$size = sprintf('%u', filesize($path));
$speed = (is_int($speed) === true) ? $size : intval($speed) * 1024;
header('Expires: 0');
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $size);
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Transfer-Encoding: binary');
for ($i = 0; $i <= $size; $i = $i + $speed)
{
ph()->HTTP->Flush(file_get_contents($path, false, null, $i, $speed));
ph()->HTTP->Sleep(1);
}
exit();
}
return false;
}
Другим вариантом является использование менее оптимизированных функций fopen()
, feof()
, fgets()
и fclose()
, , особенно если вы хотите получить сразу все строки, здесь fooobar.com/questions/56559/...:
function SplitSQL($file, $delimiter = ';')
{
set_time_limit(0);
if (is_file($file) === true)
{
$file = fopen($file, 'r');
if (is_resource($file) === true)
{
$query = array();
while (feof($file) === false)
{
$query[] = fgets($file);
if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1)
{
$query = trim(implode('', $query));
if (mysql_query($query) === false)
{
echo '<h3>ERROR: ' . $query . '</h3>' . "\n";
}
else
{
echo '<h3>SUCCESS: ' . $query . '</h3>' . "\n";
}
while (ob_get_level() > 0)
{
ob_end_flush();
}
flush();
}
if (is_string($query) === true)
{
$query = array();
}
}
return fclose($file);
}
}
return false;
}
Какой метод вы используете, будет зависеть от того, что вы пытаетесь сделать (как вы можете видеть с помощью функции импорта SQL и функции загрузки), но вам всегда нужно будет прочитать данные в кусках.
Ответ 3
$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
$line = fgets($file_handle);
echo $line;
}
fclose($file_handle);
- Откройте файл и сохраните его в
$file_handle
в качестве ссылки на сам файл.
- Проверьте, находитесь ли вы уже в конце файла.
- Продолжайте читать файл до тех пор, пока вы не закончите, напечатайте каждую строку при ее прочтении.
- Закройте файл.
Ответ 4
Вы можете использовать file_get_contents
Пример:
$homepage = file_get_contents('http://www.example.com/');
echo $homepage;
Ответ 5
Используйте fpassthru или readfile.
Оба используют постоянную память с увеличением размера файла.
http://raditha.com/wiki/Readfile_vs_include
Ответ 6
foreach (new SplFileObject($filepath) as $lineNumber => $lineContent) {
echo $lineNumber."==>".$lineContent;
//process your operations here
}
Ответ 7
Чтение всего файла за один раз происходит быстрее.
Но огромные файлы могут съесть всю вашу память и вызвать проблемы. Тогда ваша самая безопасная ставка - читать по строкам.
Ответ 8
Если вас не беспокоит объем памяти и размер файла,
$lines = file($path);
$lines - это массив файла.
Ответ 9
Вы можете попробовать cURL (http://php.net/manual/en/book.curl.php).
Altho, вы можете проверить, у него есть свои ограничения.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec ($ch); // Whole Page As String
curl_close ($ch);