Как использовать PHP для удаления X количества строк с начала текстового файла?

Использование прокси может помочь, во многих случаях мы не можем изменить код, но мы можем создать прокси и делать то, что вы хотите.

используйте следующий код:

public class Lion implements Animal {
    @Override
    public void eat() {
        System.out.println("Lion can eat");
    }
public static AtomicInteger counts = new AtomicInteger(0);
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Lion.class);
        enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> {
            counts.getAndIncrement();
            return proxy.invokeSuper(obj, args1);
        });
        Animal lion = (Lion) enhancer.create();
        lion.eat();
        lion.eat();
        lion.eat();

        System.out.println("method called " + counts.get() + " times");
    }
}

зависимость от cglib

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.10</version>
    </dependency>
6
задан Sam 10 August 2014 в 09:33
поделиться

7 ответов

$x_amount_of_lines = 30;
$log = 'path/to/log.txt';
if (filesize($log) >= $max_size)) {
  $file = file($log);
  $line = $file[0];
  $file = array_splice($file, 2, $x_amount_of_lines);
  $file = array_splice($file, 0, 0, array($line, "\n")); // put the first line back in
  ...
}

править: с исправлением от rcar и сохранением первой строки.

4
ответ дан 8 December 2019 в 03:14
поделиться

Используйте SPL, Luke

PHP 5 идет с большим количеством совершенства итераторов:

<?php

$line_to_strip = 5;
$new_file = new SplFileObject('test2.log', 'w');

foreach (new LimitIterator(new SplFileObject('test.log'), $line_to_strip) as $line)
    $new_file->fwrite($line);    

?>

Это более чисто, что, что можно сделать при питании с fopen, он не содержит весь файл в памяти, только одна строка за один раз, и можно включить его и снова использовать шаблон где угодно, так как это - полное OO.

20
ответ дан 8 December 2019 в 03:14
поделиться

Вы могли использовать файл () функция, чтобы считать файл в массив строк, затем использовать array_slice () для удаления первого X строк.

$X = 100; // Number of lines to remove

$lines = file('log.txt');
$first_line = $lines[0];
$lines = array_slice($lines, $X + 2);
$lines = array_merge(array($first_line, "\n"), $lines);

// Write to file
$file = fopen('log.txt', 'w');
fwrite($file, implode('', $lines));
fclose($file);
2
ответ дан 8 December 2019 в 03:14
поделиться

Это - проблема учебника файлов журнала, и я хотел бы предложить другое решение.

Проблема со "строками удаления в начале файлов" подход состоит в том, что добавление новых строк становится чрезвычайно медленным, после того как это должно удалить первые строки для каждого новые строки, которые это пишет.

Нормальный файл журнала, добавляющий только, включает запись еще нескольких байтов в конце файла в файловой системе (и время от времени это должно выделить новый сектор, который приводит к обширной фрагментации - почему файлы журнала обычно).

Но большая проблема здесь состоит в том при удалении строки в начале для каждой записанной строки. Весь файл должен сначала быть считан в память и затем переписан, приведя к огромной сумме ввода-вывода к жесткому диску (в сравнении). Чтобы усугубить положение, "разделение в массив PHP и пропустить первые строки" решения здесь является чрезвычайно медленным из-за природы массивов PHP. Это не проблема, если предел размера файла журнала является очень маленьким или если он записан в редко, но с большим количеством записей (как в случае с файлами журнала), та же огромная операция должна быть сделана много времен, приведя к главным недостаткам производительности.

Это может быть предположено как парковка автомобилей на строке с пространством для 50. Парковка первых 50 автомобилей быстра, просто управляйте в позади автомобиля infront и сделанный. Но когда Вы доходите до 50, и автомобиль в передней стороне (начало файла) должен быть удален, необходимо управлять 2'nd автомобиль к 1'st положение, 3-е к 2-му и так далее, прежде чем можно будет управлять в с последним автомобилем на 50'th положение. (И это должно быть повторено для каждого нового автомобиля, который Вы хотите парковать!)

Мое предложение вместо этого сохраняет к различным файлам журнала, datewise, и затем сохраните максимум 30 дней назад и т.д. Таким образом используя в своих интересах файловую систему, которая уже решила эту проблему отлично.

4
ответ дан 8 December 2019 в 03:14
поделиться

Если можно выполнить команду Linux, попробовать split. Это позволяет Вам разделять с методической точностью количество для создания вещей легкими.

Иначе я думаю, что необходимо будет считать его в и записать в 2 других файла.

0
ответ дан 8 December 2019 в 03:14
поделиться

Кроме того, к ответу @Greg, можно читать - во всем файле в массив, пропустить первое X много записей, затем переписать массив в файл.

Как подход: http://us3.php.net/manual/en/function.file-get-contents.php

$fle = file_get_contents("filename");
// skip X many newlines, overwriting the contents of the string with ""
// http://us3.php.net/manual/en/function.file-put-contents.php
file_put_contents("filename", $fle);
0
ответ дан 8 December 2019 в 03:14
поделиться

Типичные операционные системы не обеспечивают возможность вставить или удалить содержание "оперативного" файла. То, что необходимо будет сделать, записать функцию, которая читает первый файл и создает новый выходной файл, содержащий строки, которые Вы хотите сохранить. Затем, когда Вы сделаны, удаляете старый файл и переименовываете новый к старому названию.

В псевдокоде:

open original file IN for reading
create new output file OUT
read the first two lines from IN
write these lines to OUT
for each line to skip:
    read a line from IN
for the remainder of the file:
    read a line from IN
    write the line to OUT
close IN
close OUT
delete IN
rename OUT to IN

Преимущество этого метода по некоторым из других представленных состоит в том, что он не требует, чтобы Вы считали целый файл в память сначала. Вы не упоминали, насколько большой Ваш верхний предел размера был, но если это - что-то как 100 МБ, Вы могли бы найти, что загрузка файла в память не является приемлемым использованием пространства.

0
ответ дан 8 December 2019 в 03:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: