【问题标题】:Is fopen() limited by the filesystem?fopen() 是否受文件系统限制?
【发布时间】:2010-11-19 21:28:37
【问题描述】:

我编写了一个程序来生成大型 .SQL 文件,以便快速填充非常大的数据库。我用 PHP 编写了脚本。当我开始编码时,我使用的是 fopen()fwrite()。当文件变得太大时,程序会将控制权返回给 shell,并且文件将不完整。

不幸的是,我不确定“太大”到底有多大。我认为它可能在 4GB 左右。

为了解决这个问题,我将文件 echo 保存到标准输出。当我像这样调用程序时,我重定向了它:

[root@localhost]$ php generatesql.php > myfile.sql

这就像一个魅力。我的输出文件最终约为 10GB。

那么,我的问题是:fopen()fwrite() 是否受到文件系统的限制,它们能够生成多大的文件?如果是这样的话;这是PHP的限制吗?其他语言也会出现这种情况吗?

【问题讨论】:

  • 显示一些代码...可能是因为您使用的是 32 位操作系统,并且您超出了文件位置的 int 限制(但这只是推测,除非您调用 @987654322 @ 或 fseek)...
  • 我一从办公室回到家就会显示一些代码。
  • @ircmaxell: fseek() 在执行的最后被调用。

标签: php fopen fwrite


【解决方案1】:

可能发生的情况是底层 PHP 构建是 32 位,无法处理 >4GB 的文件指针 - 请参阅 related question

您的底层操作系统显然能够存储大文件,这就是您能够将标准输出重定向到大文件的原因。

顺便说一句,SQL 文件可能是高度可压缩的,因此您可能会考虑使用gzip fopen wrapper 在编写文件时对其进行压缩。

$file = 'compress.zlib:///path/to/my/file.sql.gz';
$f = fopen($file, 'wb');

    //just write as normal...
    fwrite($f, 'CREATE TABLE foo (....)');

fclose($f);

您的转储将是原始大小的一小部分,您只需将输出从zcat 传送到 SQL 客户端即可恢复它,例如对于mysql

zcat /path/to/my/file.sql.gz | mysql mydatabase

【讨论】:

【解决方案2】:

是和不是。它不是 fopen()fwrite() 直接受到限制,它的文件不能超过某些尺寸,具体取决于文件系统。看看维基百科上的Comparison of filesystems

【讨论】:

  • 但如果是这样的话,输出重定向如何为 OP 生成约 10 GB 的文件?
  • 为什么不呢? f*()(“文件”-函数)通常在流上工作。因此,如果您调用 fwrite(),它最多只能缓冲(我假设)4kB,然后将输出直接写入打开的流(fopen() 的返回值) .现在您的脚本运行并运行并填充文件,但由于最大文件大小,文件系统有时会阻止任何进一步的数据。事实上,我不知道,如果这真的发生在你身上,因为 10GB 是一个奇数。无论如何:尝试将其拆分为多个文件(比如说
【解决方案3】:

是否有可能是您的脚本执行时间过长并已超时?

或者,您是否有可能达到脚本中的内存限制?

【讨论】:

  • 使用 php-cli 执行;绝对不是超时问题。如果达到内存限制,则会出现错误消息。
【解决方案4】:

您可以在 stream 中写入超过 2GB 的数据,而不是在 文件 中(因为文件的 fseek 内部指针超出了 PHP 限制,并且流是通常不可搜索)

<? $target = fopen('test.tar', 'w'); //this is a file, limited by php to 2GB $body = str_repeat("===", 1024 * 1024); while(true) fwrite($target, $test);

<? $target = popen('cat > test.tar', 'w'); //this is a stream, no limitation here $body = str_repeat("===", 1024 * 1024); while(true) fwrite($target, $test);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2012-10-04
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多