|
|
|
| есть файл состоящий из 300000 строк. (причем длина строки всегда разная, строка заканчивается символом возврата коретки)
как, указав номер строки, получить в переменную $string эту строку. | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 17:56)
| | . | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 18:13)
| | возможно ли это? | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 17:56)
| |
<?php
// $str_num - номер строки, нумерация начинается с нуля. Если нумерация с 1, то надо в качестве
// индекса массива указать $str_num-1
// data.txt - это файл
$lines = file("data.txt");
$string = $lines[$str_num];
?>
|
| |
|
|
|
|
|
|
|
для: WebTech
(29.05.2006 в 18:49)
| | тада такой вопрос, как сделать вытаскивание всех строк в массив $string[$str_num]?
вопервых до конца файла лезть надо.
вовторых если файл огроменный, к примеру, будет, то фунцией file не рекомендовано пользоваться.. | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 19:22)
| | Бред. file() не является безопастной в плане двоичных файлов. А так открывай и считывай в масссив, затем циклом ищи что надо. Что здесь тяжелого? | |
|
|
|
|
|
|
|
для: WebTech
(29.05.2006 в 18:49)
| | тада такой вопрос, как сделать чтение всех строк в массив $string[$str_num]?
1. надо лезть до конца файла
2. если файл большой будет, то это функцией не рекомендованно пользоваться. | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 19:24)
| | реально погонял эту функцию на файл весом в 103 мб... сервак думает около секунды, что не есть хорошо...
а этих файлов знаешь сколько =)... реально сервак потухнет на сутки =) | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 19:34)
| | Файлы не меняются? Тогда стройте индексы к файлам.
Либо перегоняйте содержимое в БД. | |
|
|
|
|
|
|
|
для: Trianon
(29.05.2006 в 19:43)
| | два файла в сутки пишуться каждые 15 минут, причем мега на два - три.
цель задачи загнать данные в БД.. файл обрабатывается построчно...
попробовал запустить на серваке функцию для работы с файлом в 103 мб сервер призадумался чуть... а это плохо...
еще нужно решить задачу перегона данных из дописанных файлов и тоже надо обрабатывать построчно... т.е. надо узнать конец файла и от начала парпарсить все строки. как в случае с данным вариантом поступить? | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 19:51)
| | Они каждые 15 минут с нуля перезаписываются до трех метров? Или раз в 15 минут идет дозапись в хвост файла?
Зачем нужен доступ к произвольной строке? Почему нельзя обойтись последовательным? | |
|
|
|
|
|
|
|
для: Trianon
(29.05.2006 в 20:21)
| | дозаписываются в хвост...
нужно брать строку, обрабатывать и переходить к следующей...
причем нужно после дозаписи начинать с того места где закончили.. (15 минут это общий интервал, бывает и 16 бывает и 30 минут, а может и 5... я так понимаю нужно запускать скрипт каждый час и парсить его с того места где остановились, построчно)
если возможно последовательно, то как это реализовать
кста, еще вопрос чем лучше(быстрее) парсить регулярными выражениями или функциями php? | |
|
|
|
|
|
|
|
для: kaoz
(29.05.2006 в 20:59)
| | Открыть файл.
Спозиционироваться в нужную точку функцией fseek. Первый раз позиция этой точки равна нулю.
Потом просто читать файл в цикле с помощью fgets, и обрабатывать данные - заносить в БД, как я понимаю, пока не будет достигнут конец файла.
После этого считать позицию функцией ftell и сохранить её до следующего вызова. В той же базе например.
Лучше будет читать и записывать строки по несколько сотен (или тысяч) строк за раз.
(Где-то на форуме я даже как-то давал пример, как это можно делать.) Процесс при этом ускоряется в десятки-сотни раз.
PS. нашел эту тему ... [url=?id_forum=1&id_theme=14243 ]вот.[/url] | |
|
|
|
|
|
|
|
для: Trianon
(29.05.2006 в 21:10)
| | сделал так:
<?php
$blk_factor = 16538;
$handle = fopen(FILES_DIR."ISALOG_20060528_FWS_000.iis", "r");
$block = '';
$sep = "\n";
while (!feof($handle))
{
$block .= fread($handle, $blk_factor);
$lines = explode($sep, $block);
$cnt = count($lines);
echo $cnt."<br \>\n";
for($i=0;$i<$cnt;$i++)
{
echo "<b>".$i.": </b>";
echo $lines[$i]."<br \>\n";
// вместо эхов должна быть обработка и занесение в базу.
}
}
fclose($handle); $blk_factor = 1000;
?>
|
т.к. длина строки не фиксированная то в блок может невходить часть последней строки... как сделать чтоб он выдирал определенное кол-во строк за раз?
и можно сделать так чтоб в базу за один запрос загналось несколько строк? | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 12:22)
| | Спозиционироваться в нужную точку функцией fseek. Первый раз позиция этой точки равна нулю.
Потом просто читать файл в цикле с помощью fgets, и обрабатывать данные - заносить в БД, как я понимаю, пока не будет достигнут конец файла.
После этого считать позицию функцией ftell и сохранить её до следующего вызова. В той же базе например.
можно код привести в пример... а то чето в файлы врубиться немогу :( | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 12:23)
| | . | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 12:23)
| |
session_start();
$pos = $_SESSION['pos'];
$fp = fopen("file.txt", "rb");
fseek($fp, $pos, SEEK_SET);
while(!feof($fp))
{
// здесь чтение и обработка.
$line = fgets($fp); // этот вызов нужно будет поменять на код, который вытаскивает блоки строк
//......
}
$pos = ftell(fp);
$_SESSION['pos'] = $pos;
|
| |
|
|
|
|
|
|
|
для: Trianon
(30.05.2006 в 13:06)
| | ок за этот код спасибо, а как сделать вытаскивание блоков, к примеру, по 100 строк? | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 13:11)
| | А для Вас принципиально, чтобы именно по 100?
Код под ссылкой занимался именно этим.
Вытаскивал за раз много строк. Сколько поместилось.
Потом все эти строки обрабатывались иодним запросом уходили в базу.
Базе совсем не обязательно, чтобы в нее именно по 100 заливали. База не человек. | |
|
|
|
|
|
|
|
для: Trianon
(30.05.2006 в 13:18)
| | по 100 не принципиально, можно в принципе сделать переменную где указывается сколько строк, хоть одна...
попробовал код под ссылкой, работает но не совсем так как надо...
дело в том что у меня не фиксированная длина строки, и тем кодом очень часто не захватывается последняя строка до конца...
а мне нужно чтобы я указал 100 строк, к примеру и он мне сохранил в массив 100 полных строк.. | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 13:31)
| | Тот код тоже расчитан на переменную длину строки. То, что в примере были одинаковые строки, еще ни о чем не говорит. Я проверял код и на строках произвольной длины.
И начальная часть строки, недочитанной при предыдущем чтении, дописывается в начало буфера при последующем. Так что ничего не пропадает.
Как читать одной операцией конкретное количество строк произвольной длины, я, лично, не знаю. По-моему, это просто неосуществимо. | |
|
|
|
|
|
|
|
для: Trianon
(30.05.2006 в 13:47)
| | то что ничего не пропадает, понятно...
но вот как определять что это продолжение строки и как определить что в этом продолжении? | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 13:54)
| | Это делали те строки, которые Вы почему-то выбросили:
$block = $cnt <= 1 || substr($block,-1,1) == $sep
? "" : $lines[--$cnt];
if($block != "")
unset($lines[$cnt]);
|
| |
|
|
|
|
|
|
|
для: Trianon
(30.05.2006 в 14:01)
| | я что-то не понял как это работает...
вы не могли бы прокоментировать? | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 14:11)
| |
<?php
$blk_factor = 40000;
$handle = fopen($filename, "r"); // открываем файл
$block = ''; // при первом чтении в буфере предчтения пусто.
$sep = "\n"; // строки в файле разделены символом LF
while (!feof($handle)) // пока не достигнем конца файла
{ // дописываем к буферу очередной большой блок макс.размером $blk_factor
$block .= fread($handle, $blk_factor);
// разбиваем блок на строки и помещаем их в массив $lines
$lines = explode($sep, $block);
// вычисляем количество строк
$cnt = count($lines);
$block = $cnt <= 1 // если строка одна или ни одной, а также если
|| substr($block,-1,1) == $sep // последняя строка попала в буфер целиком
? "" //то мы всё обработаем до конца, и буфер будет пуст.
: $lines[--$cnt]; // иначе обрывок оставим в буфере, а число строк уменьшим
if($block != "") //
unset($lines[$cnt]); // и удалим обрывок из массива.
foreach($lines as $line)
echo $line.'<br>';
}
|
| |
|
|
|
|
|
|
|
для: Trianon
(30.05.2006 в 14:32)
| | т.е. недозаписанная строка попадает в следующий блок? | |
|
|
|
|
|
|
|
для: kaoz
(30.05.2006 в 14:39)
| | Недочитанная, а не недописанная. Да. | |
|
|
|
|
|
|
|
для: Trianon
(30.05.2006 в 14:41)
| | вы меня поняли :)
крута, большое спасибо!! | |
|
|
|