PHP Conference Japan 2024

gzread

(PHP 4, PHP 5, PHP 7, PHP 8)

gzread二進位安全的 gz 檔案讀取

描述

gzread(resource $stream, int $length): string|false

gzread() 從指定的 gz 檔案指標讀取最多 length 個位元組。當讀取到 length 個(未壓縮)位元組或到達 EOF 時停止讀取,以先發生者為準。

參數

stream

gz 檔案指標。它必須是有效的,並且必須指向由 gzopen() 成功開啟的檔案。

length

要讀取的位元組數。

傳回值

讀取的資料,或在失敗時傳回 false

變更日誌

版本 描述
7.4.0 此函數現在會在失敗時傳回 false;先前是傳回 0

範例

範例 #1 gzread() 範例

<?php
// 將 gz 檔案的內容讀入字串
$filename = "/usr/local/something.txt.gz";
$zd = gzopen($filename, "r");
$contents = gzread($zd, 10000);
gzclose($zd);
?>

參見

  • gzwrite() - 二進位安全的 gz 檔案寫入
  • gzopen() - 開啟 gz 檔案
  • gzgets() - 從檔案指標取得一行
  • gzgetss() - 從 gz 檔案指標取得一行並移除 HTML 標籤
  • gzfile() - 將整個 gz 檔案讀入陣列
  • gzpassthru() - 輸出 gz 檔案指標上的所有剩餘資料

新增註解

使用者貢獻的註解 9 則註解

8
Nitrogen
12 年前
這是一個用於傳回 gzip 檔案的未壓縮檔案大小的函數。檔案大小以 32 位元整數形式儲存在壓縮檔案的結尾,這就是此函數的工作原理。此外,此函數會先檢查它是否為真正的 gzip 壓縮檔案,然後再執行此操作;如果不是,則就像其他 gz- 函數一樣,它會將其視為一般檔案並執行一般檔案大小操作。請享用!

<?php

function gzfilesize($filename) {
$gzfs = FALSE;
if((
$zp = fopen($filename, 'r'))!==FALSE) {
if(@
fread($zp, 2) == "\x1F\x8B") { // 這是 gzip 壓縮檔案
fseek($zp, -4, SEEK_END);
if(
strlen($datum = @fread($zp, 4))==4)
extract(unpack('Vgzfs', $datum));
}
else
// 不是 gzip 壓縮檔案,還原為一般檔案大小函數
$gzfs = filesize($filename);
fclose($zp);
}
return(
$gzfs);
}

?>
4
waldermort at gmail dot com
7 年前
在迴圈中讀取資料時請小心。gzread() 的行為與 bzread() 或 fread() 有點不同,它在讀取超過資料流結尾時「不會」傳回 false。它會改為傳回空字串。

因此像這樣的迴圈
$handle = gzopen($file);
while (false !== $chunk = gzread($handle, $bytes)) {
//...
}

將會無限迴圈。
1
robinv12001 at yahoo dot co dot in
15 年前
<?php
// 使用 FTP 從遠端伺服器下載當天日期的 gzip 檔案
// gzip 檔案會被解壓縮
function parse_rawlist( $array )
{
$i=0;
foreach(
$array as $curraw)
{
$struc = array();
$current = preg_split("/[\s]+/",$curraw,9);

$struc['perms'] = $current[0];
$struc['number'] = $current[1];
$struc['owner'] = $current[2];
$struc['group'] = $current[3];
$struc['size'] = $current[4];
$struc['month'] = $current[5];
$struc['day'] = $current[6];
$struc['time'] = $current[7];
$struc['zfile_name'] = $current[8];
$structure[$i] = $struc;
$i++;
}
return
$structure;

}
ini_set('memory_limit', '100M');

//在此處提供 FTP 資訊
//------------------------------------------------------------
$ftp_server = "example.com";
$ftp_user_name = "example";
$ftp_user_pass = "test";
//------------------------------------------------------------
//------------------------------------------------------------
$local_path = '/opt/lampp/htdocs/sample/test.gz';//本機路徑
$server_path = 'outgoing/folder/';//遠端伺服器路徑
//------------------------------------------------------------

$conn_id = ftp_connect($ftp_server,21);
if(
$conn_id)
{
echo
"成功連線";
}

$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
ftp_chdir($conn_id, $server_path);//變更目前工作目錄
$file_list = ftp_rawlist($conn_id,".");
$zip_details = parse_rawlist($file_list);
set_time_limit(1000);
$curr_date = strtotime(date("F d Y"));
for(
$i=0;$i<count($zip_details);$i++)
{
$fname = $zip_details[$i]['zfile_name'];
$mod_date1 = $zip_details[$i]['month']." ".$zip_details[$i]['day']." ".date("Y");
$mod_date = strtotime($mod_date1);//檔案修改日期
if($mod_date == $curr_date)//如果修改日期等於當天日期
{
$local_file = $fname;
$server_file = $fname;
if (
ftp_get($conn_id, $local_file, $server_file, FTP_BINARY))
{

echo
"<br/>成功寫入 $local_file\n";
}
else
{
echo
"<br/>發生問題\n";
}
if(
file_exists($local_file))
{
$fzip_size = $zip_details[$i]['size'];
$filename = $local_file;
$ext = pathinfo($filename,PATHINFO_EXTENSION);
$file_name = pathinfo($filename,PATHINFO_FILENAME);
$file_name = $file_name.".csv";
$zd = gzopen($filename, "r");
$contents = gzread($zd, $fzip_size);
$file_name = "uploads/".$file_name;
file_put_contents($file_name,addslashes($contents));
if(
file_exists($file_name))
{
chmod($file_name,0755);
unlink($local_file);
}
gzclose($zd);
}
}
}
ftp_close($conn_id);
?>
2
utku
16 年前
我不認為將整個 gzip 檔案(它是為了某種原因而壓縮的,並且很可能是一個非常大的檔案)讀入單一字串是明智的。您很可能會達到 php 的記憶體限制。相反地,如果您需要處理該檔案,請將您的 gzread 呼叫放入迴圈中,並以常數值設定 $length 來逐步讀取。
0
imp
1 年前
最大 $length 為 2147483647 位元組 (2^32-1)。

否則 gzread() 將返回 false。
0
denis at bitrix dot ru
14 年前
請注意,此函數在 EOF 的情況下,行為與 fread 不同。

當您讀取最後一個區塊(意味著檔案的最後幾個位元組)時,在 gzread 之後就是 EOF,但在 fread 的情況下,您需要再讀取一次才能得到 EOF。

希望我表達清楚了 :)
0
robinv12001 at yahoo dot co dot in
15 年前
<?php
//在 php 中解壓縮 gzip 檔案的內容,並使用該內容建立新的 csv 檔案
//在目前資料夾中建立 uploads 資料夾
$local_file = 'test.gz';

//取得未壓縮檔案的大小
$FileRead = $local_file;
$FileOpen = fopen($FileRead, "rb");
fseek($FileOpen, -4, SEEK_END);
$buf = fread($FileOpen, 4);
$GZFileSize = end(unpack("V", $buf));
fclose($FileOpen);
//取得 zip 檔案的大小

$fzip_size = $GZFileSize;

$filename = $local_file;
$ext = pathinfo($filename,PATHINFO_EXTENSION);
$file_name = pathinfo($filename,PATHINFO_FILENAME);
$file_name = $file_name.".csv";

$zd = gzopen($filename, "rb");
$contents = gzread($zd, $fzip_size);
gzclose($zd);
$file_name = "uploads/".$file_name;
$fp = fopen($file_name, "wb");
fwrite($fp, $contents); //將 feed 的內容寫入快取檔案
fclose($fp);
if(
file_exists($file_name))
{
chmod($file_name,0755);
unlink($local_file);
}
?>
0
zaotong at yahoo dot com
17 年前
如同我在另一個論壇中被告知的,有一種方法可以透過檢視 gz 檔案的最後 4 個位元組來取得 gz 檔案的未壓縮大小。

這是一段可以做到這一點的程式碼
<?php
$FileRead
= 'SomeText.txt';
$FileOpen = fopen($FileRead, "rb");
fseek($FileOpen, -4, SEEK_END);
$buf = fread($FileOpen, 4);
$GZFileSize = end(unpack("V", $buf));
fclose($FileOpen);
$HandleRead = gzopen($FileRead, "rb");
$ContentRead = gzread($HandleRead, $GZFileSize);
?>

這將讀取 gz 檔案的最後 4 個位元組,並將其用作 gzread 的檔案整數。

感謝 stereofrog 協助我撰寫這段程式碼。
-3
calin_ip at yahoo dot com
14 年前
關於找出 gz 檔案的長度。
由於某些原因,seek() 函式沒有運作,因此我嘗試使用字串函式找出最後 4 個位元組。
這效果很好。這是程式碼。
<?php
$stringu
='my_beautiful_file.txt.gz';
$gzip=file_get_contents($stringu);
$rest = substr($gzip, -4);
$GZFileSize = end(unpack("V", $rest));

$FileRead = $stringu;
$HandleRead = gzopen($FileRead, "rb");
$ContentRead = gzread($HandleRead, $GZFileSize);
gzclose($HandleRead);
?>
To Top