2017-08-16 52 views
1

我通过运行几个外部的Unix工具在PDF文件中写入一个临时文件(基本上我使用QPDF和sed改变颜色值不要问。):从临时文件流,然后删除完成后?

// Uncompress PDF using QPDF (doesn't read from stdin, so needs tempfile.) 
$compressed_file_path = tempnam(sys_get_temp_dir(), 'cruciverbal'); 
file_put_contents($compressed_file_path, $response->getBody()); 
$uncompressed_file_path = tempnam(sys_get_temp_dir(), 'cruciverbal'); 
$command = "qpdf --qdf --object-streams=disable '$compressed_file_path' '$uncompressed_file_path'"; 
exec($command, $output, $return_value); 

// Run through sed (could do this bit with streaming stdin/stdout) 
$fixed_file_path = tempnam(sys_get_temp_dir(), 'cruciverbal'); 
$command = "sed s/0.298039215/0.0/g < '$uncompressed_file_path' > '$fixed_file_path'"; 
exec($command, $output, $return_value); 

所以,当这样做完成后,我在磁盘上留下一个临时文件$fixed_file_path。 (注:虽然我可以做整个sed过程内存流没有一个临时文件中,QPDF实用requires an actual file as input,有很好的理由)

在我现有的过程中,我再读取整个$fixed_file_path文件中作为一个字符串,删除它,然后将该字符串交给另一个类去处理。

我现在想的是最后一部分改变为使用PSR-7流,即\Guzzle\Psr7\Stream对象。我认为它会更有记忆效率(我可能会同时在空中播放其中的一些),最终它需要成为一个流。

但是,我不知道如何删除临时文件,当我将流关闭的(第三方)类完成了。有没有一种方法说“......并在完成后删除它”?或以其他方式自动清除临时文件,而无需手动跟踪它们?

我已经隐约考虑我自己的滚动SelfDestructingFileStream,但似乎有点小题大做,我想我可能失去了一些东西。

+0

'shell_exec'将从命令返回完整输出。为什么你输出到一个文件呢? – mpen

+0

@mpen嗯,基本上是因为这是一个快速而肮脏的过程。我现在正在尝试清理它,我一定会考虑直接从流程中读取'sed'的结果。不过,我记得好象QPDF,前面的过程中,不处理流那么好,可能是因为PDF文件都不是“流j”(他们不写在流有用的顺序),所以我有一个临时文件已经躺在身边了。 –

+1

你在'\狂饮\ PSR7 \ Stream'将引入的开销,除非你已经拥有了与狂饮/ PSR7流工作类。如果使用正确的方法,PHP内置了对流的支持。 QPDF可能需要在整个文件开始处理之前缓冲整个文件到内存中,它可能不会输出任何东西,直到它完全完成,但仍然可以在PHP方面使用流。如果它利用它们,太棒了!节省更多的内存。如果没有,我不认为它会伤害任何人。 – mpen

回答

1

听起来像是你想要的东西是这样的:

<?php 

class TempFile implements \Psr\Http\Message\StreamInterface { 

    private $resource; 

    public function __construct() { 
     $this->resource = tmpfile(); 
    } 

    public function __destruct() { 
     $this->close(); 
    } 

    public function getFilename() { 
     return $this->getMetadata('uri'); 
    } 

    public function getMetadata($key = null) { 
     $data = stream_get_meta_data($this->resource); 
     if($key) { 
      return $data[$key]; 
     } 
     return $data; 
    } 

    public function close() { 
     fclose($this->resource); 
    } 

    // TODO: implement methods from https://github.com/php-fig/http-message/blob/master/src/StreamInterface.php 
} 

有QPDF写$tmpFile->getFilename(),然后你可以把整个对象给您的狂饮/ POST,因为它是PSR-7标准,然后将文件在超出范围时将自行删除。

+0

谢谢,这种方法似乎工作正常。我使用了方便的[StreamDecoratorTrait](https://github.com/guzzle/psr7#implementing-stream-decorators)来避免必须手动实现其他流方法。 –

+0

@MattGibson很好。不知道那个特质。感谢分享:-D – mpen

+1

没问题。我很高兴有一些保证,我的模糊计划正沿着大致理性的路线前进...... –

相关问题