问题
I'm currently using the Archive-Tar Pear extension for PHP to add a collection of files into a Tar Archive.
These files are stored on a filer with an extra extension e.g.
filename.tgz.104850209.t or filename2.doc.2154395.t
I'd like to remove this extra extension while adding the files so that my Tar Archive would have the files: filename.tgz and filename2.doc
Is there a way of doing that without having to copy/rename the source files first before adding to the Archive?
Thanks, Mark.
回答1:
Archive_Tar
in its latest version does not yet support such a functionality out of the box. Part of the functionality is in _addFile()
and the other part in _addString()
.
Most easy is probably to extend from Archive_Tar
and proxy all calls to _writeHeaderBlock() which is public, applying a map on the filename parameter so to rename it when written into headers.
class Patched_Archive_Tar extends Archive_Tar
{
var $renameMap = array();
function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0,
$p_type='', $p_uid=0, $p_gid=0)
{
return parent::_writeHeaderBlock($this->_translateFilename($p_filename),
$p_size, $p_mtime=0, $p_perms=0,
$p_type='', $p_uid=0, $p_gid=0);
}
function _translateFilename($orignal)
{
$map = $this->renameMap;
if (isset($map[$orignal])) {
return $map[$orignal];
}
return $original;
}
}
Usage:
$obj = new Patched_Archive_Tar('dummy.tar'); // name of archive
$files = array('mystuff/ad.gif',
'mystuff/alcon.doc.t',
'mystuff/alcon.xls.t'); // files to store in archive
$obj->renameMap = array(
'mystuff/alcon.doc.t' => 'mystuff/alcon.doc',
'mystuff/alcon.xls.t' => 'mystuff/alcon.xls',
) // files to rename
if ($obj->create($files)) {
echo 'Created successfully!';
} else {
echo 'Error in file creation';
}
This is quick and dirty but hopefully worky. For something better see the function I noticed at the beginning _addFile()
and _addString()
, you basically want another one that is able to add a file (as with _addFile()
) by specifiying the filename (as with _addString()
).
回答2:
Tried to edit @hakre's answer, but peer reviewers weren't having that.
To answer @user2248522's comment, I rewrote the class to use _writeHeader. Additionally, I added a block for any Windows users out there and fixed a couple spelling errors.
class Patched_Archive_Tar extends Archive_Tar
{
var $renameMap = array();
function _writeHeader($p_filename, $p_stored_filename)
{
return parent::_writeHeader($p_filename,
$this->_translateFilename($p_stored_filename));
}
function _translateFilename($orignal)
{
$map = $this->renameMap;
if (isset($map[$original])) {
return $map[$original];
}
//Need alter our map array to match the altered original on WIN systems
if (defined('OS_WINDOWS') && OS_WINDOWS) {
//Check for a proper array
if (!is_array($map)) return $original;
//Check each replacement rule
foreach($map as $needle => $replacement) {
if ($this->_translateWinPath($needle, true) == $original) {
return $replacement;
} //if()
} //foreach()
} //if()
return $original;
}
}
Usage:
$obj = new Patched_Archive_Tar('dummy.tar'); // name of archive
$files = array('mystuff/ad.gif',
'mystuff/alcon.doc.t',
'mystuff/alcon.xls.t'); // files to store in archive
$obj->renameMap = array(
'mystuff/alcon.doc.t' => 'mystuff/alcon.doc',
'mystuff/alcon.xls.t' => 'mystuff/alcon.xls',
) // files to rename
if ($obj->create($files)) {
echo 'Created successfully!';
} else {
echo 'Error in file creation';
}
来源:https://stackoverflow.com/questions/15831121/adding-files-to-a-tar-archive-in-php-with-different-filenames