fwrite(): XX 字节写入失败,errno=5 输入/输出错误

Posted

技术标签:

【中文标题】fwrite(): XX 字节写入失败,errno=5 输入/输出错误【英文标题】:fwrite(): write of XX bytes failed with errno=5 Input/output error 【发布时间】:2021-04-10 15:46:27 【问题描述】:

我之前有 2 个类似的问题,但是经过更多调试后,我得出结论,问题(可能)不在我自己的代码中。

在我的代码中,我试图解压缩一个 gzip 文件,为此我写了一个小方法;

<?php

namespace App\Helpers;

class Gzip


    public static function unzip($filePath)
    
        $outFilePath = str_replace('.gz', '', $filePath);

        // Open our files (in binary mode)
        $file = gzopen($filePath, 'rb');
        $outFile = fopen($outFilePath, 'wb');

        // Keep repeating until the end of the input file
        while (!gzeof($file)) 
            // Read buffer-size bytes
            // Both fwrite and gzread and binary-safe
            fwrite($outFile, gzread($file, 4096));
        

        // Files are done, close files
        fclose($outFile);
        gzclose($file);
    

这应该会导致解压缩文件;

Gzip::unzip('path/to/file.csv.gz');

这就是它变得棘手的地方,有时它会解压缩文件,有时它会抛出这个异常; (请记住,这与 StreamHandler 本身无关,这是一个纯粹的输入/输出错误问题)

我可以根据需要多次刷新页面,但不会有任何改变,如果我在命令行上尝试gunzip 命令,它将失败并排除相同的错误;

我解压哪个文件无关紧要,它随机发生在一个随机文件中。

现在,如果我多次运行 gunzip 命令也没关系,但就像我说的这些异常/错误是随机发生的,所以它们也会随机地自行“修复”它们。

该应用程序是用 Laravel 8.0 编写的,PHP7.4 在 Homestead 环境(Ubuntu 18.04.5 LTS)上运行,我的基本笔记本电脑在 Windows 10 上运行。

对我来说,这个异常/错误是随机发生的,而且是随机发生的,而且会随机地“修复”自身,这非常奇怪,所以我的问题是:这是怎么发生的,为什么会发生,最终我该如何修复它。

p>

【问题讨论】:

fopen 可能会失败,您需要检查一下。应该是文件或文件夹权限问题。 @TylerMiles 是否与gunzip 命令本身有任何关联? 如果您使用的是同一个文件,您可能会在它仍在使用时尝试使用它并收到此错误。 @apokryfos 但为什么首先会出现异常? 很难说,我建议在 repo 上向开发人员提出问题(希望在 git 上)。在循环中运行 try catch 以在失败时重试......有一个最大重试次数的计数器。即使进程因信号而停止,您的资源也不应关闭。在处理套接字资源或启动 mysql 连接时,我在自己的部分代码中执行此操作。 【参考方案1】:

errno=5 Input/output error是Linux文件系统读/写失败。

真正的服务器,需要用fsck等检查磁盘...

Homestead 在 Windows 上运行,我认为我们应该寻找 windows 10 homestead errno -5 问题。

winnfsd - https://github.com/winnfsd/vagrant-winnfsd/issues/96#issuecomment-336105685

【讨论】:

是的,这些是我的确切想法,但是我已经尝试在错误发生后重新启动 NFS 客户端。这根本没有区别,但是我仍然认为它与 Vagrant + windows 有关 没错,可惜没用,不过还是想帮你找出错误原因。另一个解决方案是 Laravel Sail。 laravel.com/docs/8.x/sail 是的,我可能不得不这样做,但是我更喜欢 vagrant(如果它有效的话。)【参考方案2】:

如果你在 Windows 上的 Vagrant 正在使用 VirtualBox,HyperV 可以解决这个问题。

尝试在 powershell 上为 VirtualBox 禁用 HyperV,然后重新启动 Windows

Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Hypervisor

问候

【讨论】:

【参考方案3】:

问题在于我使用 Homestead(一个 Vagrant 盒子)打开 NFS,Vagrant + NFS + Windows = 问题。这个问题有很多可能的解决方案,大多数关于 errno5 的例外都归结为 NFS + Vagrant。

我的解决方案是停止使用 NFS,现在这将是公认的答案,因为这解决了我的问题。但是,如果有人设法找到解决此错误的实际方法,我会接受。

【讨论】:

【参考方案4】:

我解决了它,我继续使用 NFS。

这种情况通常发生在我删除数据库架构或创建新架构并在我的虚拟框中填充大量数据时。我说的是大约 50 兆字节的卷。我想这足以让 virtual box 开始重新缩放虚拟硬盘,这让 Ubuntu 疯狂,内核恐慌。

所以解决方案是重新启动 vagrant 以解决问题。

这通常对我有用:

make vagrant halt - 会出错 然后vagrant up - 它可能不起作用 他们vagrant halt - 它可能会再次出现错误 然后vagrant up --provision - 这需要时间并且可能还会出错 然后vagrant halt - 这次应该可以工作了 然后vagrant up --provision - 因为“为什么不重新配置它”,通常就足够了。

10 例中有 9 例就足够了。不够的话我就新建一个宅基地。

【讨论】:

以上是关于fwrite(): XX 字节写入失败,errno=5 输入/输出错误的主要内容,如果未能解决你的问题,请参考以下文章

php: 怎么让写入的字符串自动换行(在文本里面)?用fwrite()写入

C fopen 写入失败,errno 为 2

了解 fwrite() 的缓冲行为

c++,fwrite(&user,sizeof(user),1,fp)啥意思?

PDO::__construct(): 发送 108 字节失败,errno=32 Broken pipe

fwrite 处理大量小写的效率