fwrite () более 2 GiB?

У меня есть набор файлов, которые я хочу объединить (каждый из них представляет собой часть из нескольких частей).

Каждый разбитый файл имеет размер около 250MiB, и у меня есть переменное число из них.

Моя логика конкатенации прямолинейна:

if (is_resource($handle = fopen($output, 'xb')) === true) { foreach ($parts as $part) { if (is_resource($part = fopen($part, 'rb')) === true) { while (feof($part) !== true) { fwrite($handle, fread($part, 4096)); } fclose($part); } } fclose($handle); } 

Мне потребовалось некоторое время, чтобы проследить его, но, судя по всему, всякий раз, когда у меня есть более 8 отдельных частей (всего 2GiB), мой выходной файл обрезается до 2147483647 байт (сообщается sprintf('%u', $output) ).

Полагаю, это связано с 32-битным внутренним счетчиком, используемым fopen() или fwrite() .

Как я могу обойти эту проблему (желательно, используя только PHP)?

В качестве обходного пути вы можете использовать оболочку. Если код должен быть портативным, это будет включать только два варианта для Windows и Linux (также охватывающих MacOS).

Linux

 cat file1.txt file2.txt > file.txt 

Windows

 copy file1.txt+file1.txt file.txt 

Обратите внимание, что при создании командной строки очень важно избегать аргументов переменной. Используйте escapeshellarg() чтобы обернуть имена файлов (см. http://de1.php.net/escapeshellarg ).

Чтобы определить, находитесь ли вы в Windows или Linux, посмотрите на постоянный PHP_OS . (лучше всего здесь: http://www.php.net/manual/en/function.php-uname.php )