You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fwrite写入大文件出现损坏,求PHP脚本修复帮助

Fixing File Corruption Issues with Your PHP DCC File-Writing Script

Hey there, let's figure out why your PHP file-writing script is causing corruption, especially with large files. I’ve looked at your code and spotted a few key issues that are likely the culprit, plus some best practices to fix them for good.

What’s Wrong with the Original Script?

Your savetofile() function has two critical problems:

  1. fgets() is text-oriented, not binary-safe: fgets() stops reading when it hits a newline character (\n or \r\n). If your DCC stream contains binary data (like images, archives, or other non-text files), any byte that matches a newline will truncate the chunk you’re reading—leading to missing data and corrupted files.
  2. Only reads one chunk: The function only reads 512 bytes once, so it’ll never fully write large files. You need to loop until the entire stream is processed.

Fixed Script with Binary-Safe Handling

Here’s a revised version of your function that addresses these issues, plus adds error checking to catch write failures:

function saveToFile($dccStream, $fileHandle) {
    $totalBytesWritten = 0;
    $chunkSize = 512; // Keep your original chunk size, or adjust to 4096 for better performance

    // Loop until we reach the end of the DCC stream
    while (!feof($dccStream)) {
        // Read a binary-safe chunk from the stream
        $chunk = fread($dccStream, $chunkSize);
        if ($chunk === false) {
            throw new RuntimeException("Failed to read from DCC stream");
        }

        $chunkLength = strlen($chunk);
        if ($chunkLength === 0) {
            break; // No more data to read
        }

        // Write the chunk to the file, and verify all bytes were written
        $bytesWritten = fwrite($fileHandle, $chunk);
        if ($bytesWritten === false || $bytesWritten !== $chunkLength) {
            throw new RuntimeException(
                "File write failed: only wrote $bytesWritten out of $chunkLength bytes"
            );
        }

        $totalBytesWritten += $bytesWritten;
    }

    return $totalBytesWritten;
}

How to Use This Function Correctly

To avoid further corruption, make sure you open both your DCC stream and output file in binary mode (using rb/wb flags). This prevents Windows systems from automatically converting newline characters, which breaks binary files.

// Example usage
$dccSource = "path/to/your/dcc/stream"; // Replace with your actual stream source
$outputFile = "path/to/save/file.bin"; // Replace with your target file path

// Open DCC stream in binary read mode
$dccStream = fopen($dccSource, 'rb');
if (!$dccStream) {
    die("Failed to open DCC stream: " . error_get_last()['message']);
}

// Open output file in binary write mode (overwrites existing file)
$fileHandle = fopen($outputFile, 'wb');
if (!$fileHandle) {
    fclose($dccStream);
    die("Failed to open output file: " . error_get_last()['message']);
}

try {
    $totalBytes = saveToFile($dccStream, $fileHandle);
    echo "Success! Wrote $totalBytes bytes to $outputFile";
} catch (RuntimeException $e) {
    echo "Error: " . $e->getMessage();
} finally {
    // Always close file handles to avoid resource leaks
    fclose($fileHandle);
    fclose($dccStream);
}

Key Best Practices to Remember

  • Binary mode is non-negotiable: Use rb for reading and wb/ab for writing when dealing with non-text files.
  • Avoid global variables: Pass streams/file handles as parameters instead of relying on $GLOBALS—this makes your code more reusable and less prone to bugs.
  • Check return values: Both fread() and fwrite() can fail silently if you don’t check their return values. Always verify that you’ve read/written the expected number of bytes.
  • Use reasonable chunk sizes: 512 bytes works, but 4096 bytes (4KB) is closer to typical filesystem block sizes and can improve performance for large files.

内容的提问来源于stack exchange,提问作者Ikuria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:12:44