Error creating backup on Windows
-
When trying to create a backup of a site that runs on Windows, I consistently get an error when the tar file is being created as soon as a directory is added. This because a call to fopen() op Windows will fail. However as a directory does not contain data and we only want to write the header block with a.o. the access rights, there’s no need to make that call to fopen(). (Note: a tar archive expects 0 or more file contents blocks after the header block, so it is correct to not write anything to the archive when the file size is 0 ( empty file or directory).
What follows is the diff of the changes I made to get it working on Windows as well. On Linux it will safe you a number of system calls (fopen,feof,fclose for each folder and empty file):
diff --git a/vendor/splitbrain/php-archive/src/Tar.php b/vendor/splitbrain/php-archive/src/Tar.php index 9550b6c..6f52666 100644 --- a/vendor/splitbrain/php-archive/src/Tar.php +++ b/vendor/splitbrain/php-archive/src/Tar.php @@ -256,33 +256,36 @@ class Tar extends Archive throw new ArchiveIOException('Archive has been closed, files can no longer be added'); } - $fp = @fopen($file, 'rb'); - if (!$fp) { - throw new ArchiveIOException('Could not open file for reading: '.$file); - } - // create file header $this->writeFileHeader($fileinfo); - // write data - $read = 0; - while (!feof($fp)) { - $data = fread($fp, 512); - $read += strlen($data); - if ($data === false) { - break; + // write data, but only if we have data to write. + // note: on Windows fopen() on a directory will fail, so we prevent + // errors on Windows by testing if we have data to write. + if (!$fileinfo->getIsdir() || $fileinfo->getSize() === 0) { + $read = 0; + $fp = @fopen($file, 'rb'); + if (!$fp) { + throw new ArchiveIOException('Could not open file for reading: ' . $file); } - if ($data === '') { - break; + while (!feof($fp)) { + $data = fread($fp, 512); + $read += strlen($data); + if ($data === false) { + break; + } + if ($data === '') { + break; + } + $packed = pack("a512", $data); + $this->writebytes($packed); } - $packed = pack("a512", $data); - $this->writebytes($packed); - } - fclose($fp); + fclose($fp); - if($read != $fileinfo->getSize()) { - $this->close(); - throw new ArchiveCorruptedException("The size of $file changed while reading, archive corrupted. read $read expected ".$fileinfo->getSize()); + if ($read != $fileinfo->getSize()) { + $this->close(); + throw new ArchiveCorruptedException("The size of $file changed while reading, archive corrupted. read $read expected ".$fileinfo->getSize()); + } } if(is_callable($this->callback)) {
Note: I reported this error earlier but only got an initial response and my solution back then was to quick as it does not allow to add the header block (with access rights) for folders to the archive. (https://www.ads-software.com/support/topic/error-could-not-open-file-for-reading-public_htmlwp-windows/#post-13001788)
- The topic ‘Error creating backup on Windows’ is closed to new replies.