- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在读取 PHP 中的流,使用 proc_open 和 fgets($stdout),试图在它进入时获取每一行。
许多 linux 程序(包管理器、wget、rsync)只使用 CR(回车)字符来表示定期“就地”更新的行,例如下载进度。我想在这些更新发生时立即捕捉它们(作为单独的行)。
目前,fgets($stdout) 只是一直读取直到 LF,所以当进度非常缓慢时(例如大文件)它会一直读取直到完全完成,然后将所有更新的行作为一个返回长字符串,包括 CR。
我已经尝试设置“mac”选项来将 CR 检测为行尾:
ini_set('auto_detect_line_endings',true);
但这似乎行不通。
现在,stream_get_line 允许我将 CR 设置为换行符,但不是将 CRLF、CR 和 LF 都视为分隔符的“包罗万象”解决方案。
我当然可以阅读整行,使用各种 PHP 方法将其拆分并用 LF 替换所有类型的换行符,但它是一个流,我希望 PHP 能够在它仍在运行时获得进度指示。
所以我的问题:
我如何从 STDOUT 管道(从 proc_open)读取直到发生 LF 或 CR,而不必等到整行都进入?
提前致谢!
我使用 Fleshgrinder 的过滤器类将流中的\r 替换为\n(参见接受的答案),并将 fgets() 替换为 fgetc() 以获得对 STDOUT 内容的更多“实时”访问:
$stdout = $proc->pipe(1);
stream_filter_register("EOL", "EOLStreamFilter");
stream_filter_append($stdout, "EOL");
while (($o = fgetc($stdout))!== false){
$out .= $o; // buffer the characters into line, until \n.
if ($o == "\n"){echo $out;$out='';} // can now easily wrap the $out lines in JSON
}
最佳答案
在使用流之前使用流过滤器规范化换行符。我根据 stream_filter_register
上的 PHP 手册页中的示例创建了以下代码来完成此操作。 .
<?php
// https://php.net/php-user-filter
final class EOLStreamFilter extends php_user_filter {
public function filter($in, $out, &$consumed, $closing)
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = str_replace([ "\r\n", "\r" ], "\n", $bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
stream_filter_register("EOL", "EOLStreamFilter");
// Open stream …
stream_filter_append($yourStreamHandle, "EOL");
// Perform your work with normalized EOLs …
编辑: Mark Baker 对您的问题发表的评论是真实的。大多数 Linux 发行版都为 STDOUT
使用行缓冲区,Apple 可能也在做同样的事情。另一方面,大多数 STDERR
流都是无缓冲的。您可以尝试将程序的输出重定向到另一个管道(例如 STDERR
或任何其他管道),看看您是否更幸运。
关于PHP:试图让 fgets() 在 CRLF、CR 和 LF 上触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27907913/
我有一个包含“CRLF”和“LF”作为行分隔符的字符串。 我只想用“LF”(空格和LF)替换“CRLF”并保持“LF”不变。 我知道,我们可以使用正则表达式来做到这一点,但我已经从现有的答案中尝试了一
我需要将所有新行分隔符更改为\r\n。在字节表中有一些\r 和一些\r\n byte[] data = (byte[])transformedToByteObject; 数据包含该字节,但我不知道如何
在 Veracode 报告中,我在一些 java 文件中收到错误 CWE 93。在静态扫描实例中,一些代码是 MimeMessage msg = new MimeMessage(session); m
这段代码: InternetAddress[] myAdrs = getAdrs(message.getToAddresses()); for (int i = 0; i Impro
我一直在尝试使用 openssl 与 smtp.gmail.com 端口 587 或 465 建立连接:openssl s_client -主机 smtp.gmail.com -端口 587 -sta
我有一个 PHP 文件,需要对其进行简单的文本更改。我使用FTP从linux服务器复制到我的Win7机器。我用 Notepad++ 打开它,打开-查看-显示符号-查看所有字符-我可以在每行前后看到CR
我们有一个数据源,它向我们发送我们需要自动导入到我们系统中的文件,但在某些记录的一个或两个字段中,这些文件中经常存在以额外 CRLF 形式出现的错误数据。该文件是一个 CSV 格式文件,最初我以为我已
我编写了一个小程序,它将多段字符串作为参数上传。当我在 Netbeans 中测试它时,它保留了 CRLF,但是当我在应用程序中实时部署它时,它会丢弃它们为什么会发生这种情况以及我该怎么办? 最佳答案
我有一个文件,我想读取每一行的字符串。如果该行不以 CRLF (\r\n) 结尾,我想打印一些内容。我通过重定向打印命令的输出来创建此文件,如下所示。 System.out.println("Test
我不知道在发送正文的所有字节后我是否应该发送下一条消息而不用 CRLF 将第一条消息的正文分隔到第二条消息的起始行。 这是根据 RFC 7230 的语法: HTTP-message = star
使用 StringBuilder 并在我的字符串中使用 Environment.NewLine,当我打开它时它显示为 CRLF,C# 中是否有其他命令输出仅显示为“LF”而不是“CRLF”? 最佳答案
我得到了一个带有 HTTP 请求内容的字符串流。如您所知,HTTP 请求以 CRLF 中断结束。但是 operator>> 不会将 CRLF 识别为正常的文件结尾。我怎样才能检测到这个 CRLF 中断
我想在我的项目中确保 CRLF(Windows 风格)行分隔符。我正在检查一些替代方案,但不确定哪一个是最好的。 期望的行为: 如果文件不是 CRLF,则 IntelliJ IDEA 显示在底部: 我
目标是使用批处理脚本执行以下操作: 从 Windows 机器中提取主机名。 在主机名值(从第 1 步获得)上应用 sha256 哈希。 我的系统主机名是:W0000000000ZQ 我的批处理脚本如下
我是 VBScript 新手。我正在尝试编写一个函数来识别打印行中是否有 CRLF。你能帮我吗? 谢谢 最佳答案 您可以简单地使用result = Instr(yourString, vbCRLF)。
这个简单的解析器预计会解析以下形式的消息 key: value\r\nkey: value\r\n\r\nkey: value\r\nkey: value\r\n\r\n 一个 EOL 作为字段分隔符
我有一个 lua 文件。它读取 2 个文件,一个“脚本”文件,一个“源”文件。 lua文件解释脚本文件并用脚本文件中的一些指令更改源文件(在内存中)。然后将此修改后的源输出到输出文件中。在 CR 之前
我试图强制我的 spring 批处理始终使用 CR-LF[EDIT] 作为行分隔符来写入文件,而不管底层系统如何。 我试图使用 FlatFileItemWriter 的 setLineSeperato
如何从一组数据中解析出不需要的字符? 我正在使用 Windows 应用程序的现有 VB.NET 代码,该应用程序使用 StreamWriter 和 Serializer 来输出交易数据的 XML 文档
实现这一点的简单方法是: import re re.split(r'(?:\r\n|\r|\n){2}', '...') 但是: >>> re.split(r'(?:\r\n|\r|\n){2}',
我是一名优秀的程序员,十分优秀!