2017-08-16 82 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

沒問題。我很高興有一些保證,我的模糊計劃正沿着大致理性的路線前進...... –

相關問題