0

I need to determine that the file exceeds the specified size while it is being written. When i reach the specified size, i must stop writing and throw a exception.

Example for a normal file:

$handle = fopen($filename, 'wb');
while (true) {
    // its work
    if (fstat($handle)['size'] + strlen($string) > BYTE_LIMIT) {
        throw SizeOverflowException::withLimit(BYTE_LIMIT);
    }

    fwrite($this->handle, $string);
}
fclose($handle);

Or i can independently count the used bytes

$handle = fopen($filename, 'wb');
$used_bytes = 0;
while (true) {
    if ($used_bytes + strlen($string) > BYTE_LIMIT) {
        throw SizeOverflowException::withLimit(BYTE_LIMIT);
    }

    fwrite($this->handle, $string);
    $used_bytes += strlen($string);
}
fclose($handle);

Example write Gzip:

$handle = gzopen($filename, 'wb9');
while (true) {
    // not work
    // fstat($handle) === false
    //if (fstat($handle)['size'] + strlen($string) > BYTE_LIMIT) {
    //    throw SizeOverflowException::withLimit(BYTE_LIMIT);
    //}

    gzwrite($this->handle, $string);
}
gzclose($handle);

Similarly for Bzip2:

$handle = bzopen($filename, 'w');
while (true) {
    // not work
    // fstat($handle) === false
    //if (fstat($handle)['size'] + strlen($string) > BYTE_LIMIT) {
    //    throw SizeOverflowException::withLimit(BYTE_LIMIT);
    //}

    bzwrite($this->handle, $string);
}
bzclose($handle);

I understand why fstat() does not work in this case, but how can i solve this problem?

Now i can calculate only how many bytes will be used in uncompressed mode.

ghost404
  • 299
  • 2
  • 16

1 Answers1

1

You can instead compress incrementally in memory using deflate_init and deflate_add, using the encoding ZLIB_ENCODING_GZIP, and write the compressed data out normally with fwrite. Then you can count the compressed bytes written and stop at your specified size.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158