Como faço para abrir um arquivo a partir da linha X para a linha Y no PHP?
Pergunta
O mais próximo que eu vi nos docs PHP, é fread () um determinado comprimento, mas isso não especificar qual linha de partida. Qualquer outra sugestão?
Solução
Você não vai ser capaz de ler a partir da linha X porque as linhas podem ser de comprimento arbitrário. Então você terá que ler desde o início da contagem do número de linhas lidas para chegar à linha de X. Por exemplo:
<?php
$f = fopen('sample.txt', 'r');
$lineNo = 0;
$startLine = 3;
$endLine = 6;
while ($line = fgets($f)) {
$lineNo++;
if ($lineNo >= $startLine) {
echo $line;
}
if ($lineNo == $endLine) {
break;
}
}
fclose($f);
Outras dicas
Sim, você pode fazer isso facilmente com SplFileObject::seek
$file = new SplFileObject('filename.txt');
$file->seek(1000);
for($i = 0; !$file->eof() && $i < 1000; $i++) {
echo $file->current();
$file->next();
}
Este é um método do href="http://de.php.net/manual/en/class.seekableiterator.php" rel="noreferrer"> SeekableIterator interface de e não ser confundida com fseek
.
E porque SplFileObject é iterable você pode fazê-lo ainda mais fácil com um LimitIterator
:
$file = new SplFileObject('longFile.txt');
$fileIterator = new LimitIterator($file, 1000, 2000);
foreach($fileIterator as $line) {
echo $line, PHP_EOL;
}
Mais uma vez, este é baseado em zero, por isso é linha de 1001 e 2001.
Infelizmente, a fim de ser capaz de ler a partir da linha de x para y linha, você precisa ser capaz de detectar quebras de linha ... e você teria que percorrer todo o arquivo. No entanto, supondo que você está não perguntando sobre isso por razões de desempenho, você pode obter linhas x
para y
com o seguinte:
$x = 10; //inclusive start line
$y = 20; //inclusive end line
$lines = file('myfile.txt');
$my_important_lines = array_slice($lines, $x, $y);
Veja: array_slice
Aqui está a solução possível :)
<?php
$f = fopen('sample.txt', 'r');
$lineNo = 0;
$startLine = 3;
$endLine = 6;
while ($line = fgets($f)) {
$lineNo++;
if ($lineNo >= $startLine) {
echo $line;
}
if ($lineNo == $endLine) {
break;
}
}
fclose($f);
?>
Bem, você não pode usar a função fseek para buscar a posição adequada porque trabalha com determinado número de bytes.
Eu acho que não é possível sem algum tipo de cache ou passando por linhas de um após o outro.
Se você está à procura de linhas, então você não pode usar fread porque isso depende de uma compensação, não o número de quebras de linha de bytes. Você realmente tem que ler o arquivo para encontrar as quebras de linha, de modo que uma função diferente é mais apropriado. fgets irá ler o arquivo linha por linha. Jogar isso em um loop e captura apenas as linhas que você deseja.
Eu estava com medo de que ... Eu acho que é o plano B, então: S
Para cada solicitação AJAX eu vou:
- Leia em uma seqüência o número de linhas que eu vou voltar para o cliente.
- Copie o resto do arquivo em um arquivo temporário.
- string de retorno para o cliente.
É de coxos, e ele provavelmente irá ser bastante lento, com mais de 10.000 arquivos linhas, mas eu acho que é melhor do que ler o mesmo uma e outra vez, pelo menos, o arquivo temporário é cada vez menor com cada pedido ... Não?