当前位置: 首页 > 面试题库 >

PHP从文件中读取最后几行的最佳方法是什么?

闻枫
2023-03-14
问题内容

在我的PHP应用程序中,我需要 从许多文件 (主要是日志) 的末尾开始读取多行
。有时我只需要最后一个,有时我需要数十或数百。基本上,我想像Unix tail 命令一样灵活。

这里有一些关于如何从文件中获取最后一行的问题(但是我需要 N 行),并给出了不同的解决方案。我不确定哪一个最好,哪个表现更好。


问题答案:

方法概述

在互联网上搜索时,我遇到了不同的解决方案。我可以将它们分为三种方法:

  • 天真 的使用file()PHP函数的人;
  • 作弊tail在系统上运行命令;
  • 强大 的使用fseek()

我最终选择了(或写出了)五个解决方案,一个 幼稚的 解决方案,一个 作弊的 解决方案和三个 强大 的解决方案。

  1. 最简洁的 天真的 解决方案,使用内置数组函数。
  2. 基于tail command的[ 唯一可能的解决方案 有一个大问题:如果tail不可用,它将无法运行,即在非Unix(Windows)或不允许系统功能的受限环境中运行。
  3. 从文件末尾读取 单个字节 以查找(并计数)换行符的解决方案 。
  4. 针对大文件进行了优化的 多字节缓冲 解决方案。
  5. 解决方案4的略微 修改版本, 其中缓冲区长度是动态的,取决于要检索的行数。

所有解决方案均 有效
。从某种意义上说,它们可以从任何文件返回任意数目的预期结果(解决方案#1除外,在大型文件的情况下,这可能会破坏PHP内存限制,不返回任何内容)。但是哪个更好?

性能测试

为了回答这个问题,我进行了测试。这些就是这样完成的,不是吗?

我准备了一个样本 100 KB文件,将/var/log目录中的不同文件结合在一起。然后,我编写了一个PHP脚本,该脚本使用这五个解决方案中的每一个从文件末尾检索
1、2,..,10、20,… 100、200,…,1000 行。每个测试重复十次(大约 5×28×10 = 1400次
测试),以毫秒为单位测量 平均经过时间

我使用PHP命令行解释器在本地开发计算机(Xubuntu 12.04,PHP 5.3.10、2.70 GHz双核CPU,2 GB
RAM)上运行脚本。

解决方案#1和#2似乎更糟。仅当我们需要阅读几行时,解决方案3才是好的。 解决方案4和5似乎是最好的。
注意动态缓冲区的大小如何优化算法:由于减少了缓冲区,执行时间在几行中要短一些。

让我们尝试更大的文件。如果我们必须读取 10 MB的 日志文件怎么办?

现在,解决方案#1到目前为止是最糟糕的:实际上,将整个10
MB文件加载到内存中并不是一个好主意。我也在1MB和100MB文件上运行测试,实际上是相同的情况。

解决方案#1是现在最好的解决方案!对于PHP而言,将10 KB的内存加载到内存中并不是什么大问题。#4和#5的表现也不错。但这是一个极端的情况:10
KB日志意味着大约150/200行…

您可以 在此处下载我的所有测试文件,源和结果

最后的想法

强烈建议在一般用例中使用
解决方案#5
:适用于每种文件大小,并且在读取几行内容时表现特别好。

如果您应该读取大于10 KB的文件,请避免使用
解决方案#1

解决方案 #2
#3
并不是我进行的每个测试的最佳选择:#2永远不会在2毫秒内运行,并且#3受到您要求的行数的严重影响(仅对1或2行有效)。



 类似资料:
  • 问题内容: 这就是我逐行处理文件的方式。但是,在这种情况下,我想在每次迭代中向处理器发送 两 行文本。(我正在处理的文本文件实际上在两行上存储了一条记录,因此每次都向处理器发送一条记录。) 用Java做到这一点的最佳方法是什么? 问题答案: 为什么不读两行呢? 假设您可以依靠输入文件中包含完整的2行数据集。

  • 问题内容: 当前,我们的Java应用程序使用制表符分隔的* .cfg文件中包含的值。我们需要更改此应用程序,以使其现在使用XML文件。 为了从此文件中读取值,使用的最佳/最简单的库是什么? 问题答案: 当然,根据您的需要有很多好的解决方案。如果只是配置,则应查看Jakarta commons- configuration 和commons- digester 。 您总是可以使用获取文档的标准JDK

  • 我需要使用php读取目录中的所有文件。所以我需要这样的回报 我的文件如下所示: 现在一切正常,但是在运行之前我必须自己输入这些文件。如何从目录中发布所有文件?现在我有这样的: 我尝试了用lolob()、scandir()和readdir(),但是我没有得到想要的结果。谢谢!

  • 问题内容: 我如何从一个大的日志文件中读取最后两行而不将其完全加载到内存中? 我需要每10秒钟阅读一次(在Win机上)…并且我被困在尝试阅读最后几行。 日志文件类似于: 谢谢! 问题答案: 您可以使用file.Seek()或file.ReadAt()几乎结束,然后向前阅读。除非您知道2行= x字节,否则您只能估计从哪里开始搜索。 您可以使用os.Stat(name)获得文件长度 这是一个基于Rea

  • 我是Cassandra的新手,我正在努力弄清楚如何存储数据,以便能够并行执行快速读取。我听说分区数据会给性能带来问题?是否可以并行读取同一分区中Cassandra表中的数据?

  • 本文向大家介绍Python实现读取文件最后n行的方法,包括了Python实现读取文件最后n行的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python实现读取文件最后n行的方法。分享给大家供大家参考,具体如下: 以上处理和日志文件格式为 读取最后一行: 更多关于Python相关内容感兴趣的读者可查看本站专题:《Python文件与目录操作技巧汇总》、《Python文本文件操作技巧汇总