背景:做物聯網時經常會有軟件上傳這種操作,上傳的軟件包文件常見的是hex和bin這兩種.
一 hex文件讀取
1 首先我們需要了解hex文件內容格式
(圖及下面說明來自網絡,侵權必刪)
:(冒號)每個Intel HEX 記錄 都由冒 號開頭 ;
LL 是 數 據 長 度域, 它 代表 記錄當 中 數 據字 節 (dd) 的 數量 ;
aaaa 是地址域, 它代表 記錄當 中 數據的起始地址;
TT是代表HEX 記錄類 型的域 , 它 可能是以下 數 據 當 中的一 個:
00 – 數 據 記錄(Data Record)
01 – 文件結 束 記錄(End of FileRecord)
02 – 擴展段地址 記錄(ExtendedSegment Address Record)
03 – 開始段地址 記錄(Start Segment Address Record)
04 – 擴展 線 性地址 記錄(Extended Linear Address Record)
05 – 開始線性地址 記錄(Extended Segment Address Record)
DD 是數 據域 , 它 代表一 個 字 節 的 數 據. 一 個記錄 可以有 許 多 數 據字 節 . 記錄當 中 數 據字 節 的 數 量必 須 和數 據 長 度域(ll) 中指定的 數字相符.
CC 是校驗 和域 , 它 表示 這個記錄 的校 驗 和. 校 驗 和的 計 算是通 過將記錄當 中所有十六 進 制 編碼數 字 對 的 值相加, 以256 爲 模 進 行以下 補 足.
表示爲:“:[1字節長度][2字節地址][1字節記錄類型][n字節數據段][1字節校驗和] ”
所以我們Php取內容的時候,可以按照"循環遍歷每一行,字符串長度小於9或者第八第九位爲01的,直接break;否則判斷第八第九位是否爲00,是的話就取值,否則continue"
2 代碼實例
if($handle = fopen($_FILES["soft_file"]["tmp_name"], "r")){
$content = str_replace(array("\r\n", "\r", "\n", "\t", ' '), '', fgets($handle));
$data = '';
while ( strlen($content) >= 9 && substr($content, 7,2)!='01') {
if(substr($content, 7,2)=='00'){
$data .= substr($content,9,-2);
}
$content = str_replace(array("\r\n", "\r", "\n", "\t", ' '), '', fgets($handle));
}
file_put_contents(".demo.v", $data);
}else{
exit('上傳失敗');
}
二 bin文件讀取
一般和嵌入式軟件那邊協調都是bin文件直接讀取,屆時將內容傳給硬件設備即可
move_uploaded_file($_FILES["soft_file"]["tmp_name"], ".demo.v")
三 設備下載軟件包時簡要說明
(我們內部是16進制傳輸,各位按照自己的規則來做,這裏做下參考)
1當hex文件上傳的時候,我們已經截取了字符串,所以只需要
file_get_contents(".demo.v')
2 當bin文件上傳的時候,則需要轉換下16進制
$file_pointer = fopen(".demo.v', "rb");
$file_read = fread($file_pointer, filesize(".demo.v'));
fclose($file_pointer);
$data = bin2hex($file_read);