Add ZIP compression details to Dump Controller Log analysis
This commit is contained in:
@@ -159,3 +159,161 @@ dumpEventLog(Cdb)
|
||||
→ parse status & data
|
||||
→ close()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ZIP 壓縮處理細節
|
||||
|
||||
### 輸出檔案
|
||||
|
||||
**dlgDumpLog.java (舊型號)**
|
||||
```
|
||||
./Log/{SN}_ControllerLog_{YYYY}_{M}_{D}_{H}_{m}_{s}.zip
|
||||
```
|
||||
|
||||
**dlgDumpLog2.java (新型號)**
|
||||
```
|
||||
Primary: ./Log/Primary_{SN}_ControllerLog.zip
|
||||
Secondary: ./Log/Secondary_{SN}_ControllerLog.zip
|
||||
合併: ./Log/{PrimarySN}_{SecondarySN}_ControllerLog_{YYYY}_{M}_{D}_{H}_{m}_{s}.zip
|
||||
```
|
||||
|
||||
### 壓縮前的暫存檔
|
||||
|
||||
| Page Code | 檔案名稱 | 說明 |
|
||||
|-----------|----------|------|
|
||||
| 0x60 | EventPage.bin | Event Log |
|
||||
| 0x61 | DebugPage.bin | Debug Log |
|
||||
| 0x62 | DiskMetadataPage.bin | Disk Metadata |
|
||||
| 0x63 | SpecialLogPage.bin | Special Log |
|
||||
| 0x64 | TelMesPages.log | Telemetry Messages |
|
||||
|
||||
### compressLog() 流程 (dlgDumpLog.java)
|
||||
|
||||
```java
|
||||
public void compressLog() {
|
||||
File[] logs = new File[5];
|
||||
for(int i=0; i<=4; i++) {
|
||||
logs[i] = getFile((byte)(i+0x60)); // 取得 5 個暫存檔
|
||||
}
|
||||
|
||||
// 建立 ZIP 檔案
|
||||
Calendar rightNow = Calendar.getInstance();
|
||||
String filename = "./Log/" + PageDataDB.sSN.trim() + "_ControllerLog_"
|
||||
+ rightNow.get(Calendar.YEAR) + "_"
|
||||
+ (rightNow.get(Calendar.MONTH)+1) + "_"
|
||||
+ rightNow.get(Calendar.DAY_OF_MONTH) + "_"
|
||||
+ rightNow.get(Calendar.HOUR) + "_"
|
||||
+ rightNow.get(Calendar.MINUTE) + "_"
|
||||
+ rightNow.get(Calendar.SECOND) + ".zip";
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(filename);
|
||||
ZipOutputStream zout = new ZipOutputStream(fout);
|
||||
zout.setLevel(5); // 壓縮等級 0-9
|
||||
|
||||
// 逐一壓縮每個檔案
|
||||
for (byte i = 0; i <= 4; i++) {
|
||||
if(logs[i].exists()) {
|
||||
ZipEntry ze = new ZipEntry(logs[i].getName());
|
||||
FileInputStream fin = new FileInputStream(logs[i]);
|
||||
zout.putNextEntry(ze);
|
||||
|
||||
// 特殊處理 Page 0x64 (TelMesPages.log)
|
||||
if(i != 0x4) {
|
||||
// 一般檔案:直接複製
|
||||
for(int c = fin.read(); c != -1; c = fin.read()) {
|
||||
zout.write(c);
|
||||
}
|
||||
} else {
|
||||
// TelMesPages.log: 每 40 bytes 為一筆記錄
|
||||
// 移除空字元 (0x00),只保留有效資料
|
||||
byte data;
|
||||
boolean skipNull = false;
|
||||
for(int j=0; j < logs[i].length()/40; j++) {
|
||||
skipNull = false;
|
||||
for(int k=0; k<40; k++) {
|
||||
data = (byte)fin.read();
|
||||
if(data == 0x0a || skipNull == true) {
|
||||
skipNull = true;
|
||||
} else {
|
||||
zout.write(data);
|
||||
}
|
||||
}
|
||||
zout.write(0x0a); // 加上換行符
|
||||
}
|
||||
}
|
||||
|
||||
zout.closeEntry();
|
||||
fin.close();
|
||||
logs[i].delete(); // 刪除暫存檔
|
||||
}
|
||||
}
|
||||
zout.close();
|
||||
}
|
||||
```
|
||||
|
||||
### compressLog() 流程 (dlgDumpLog2.java)
|
||||
|
||||
```java
|
||||
// 單一控制器壓縮
|
||||
public void compressLog(String sSN) {
|
||||
String prefix = sSN.equals(PageDataDB.sSN) ? "Primary" : "Secondary";
|
||||
String filename = "./Log/" + prefix + "_" + sSN.trim() + "_ControllerLog.zip";
|
||||
// ... 同上邏輯
|
||||
}
|
||||
|
||||
// 雙控制器合併壓縮
|
||||
public void compressLog2() {
|
||||
File[] logs = new File[2];
|
||||
logs[0] = new File(sMaterFileNamePatch); // Primary
|
||||
logs[1] = new File(sSlaveFileNamePatch); // Secondary
|
||||
|
||||
// 合併成單一 ZIP,內含兩個 ZIP 檔
|
||||
String filename = "./Log/" + PageDataDB.sSN.trim() + "_"
|
||||
+ PageDataDB.sSlaveSN.trim() + "_ControllerLog_{timestamp}.zip";
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### ZIP 結構
|
||||
|
||||
```
|
||||
Archive: {SN}_ControllerLog_2024_3_29_10_30_45.zip
|
||||
├── EventPage.bin (512 bytes/block)
|
||||
├── DebugPage.bin (512 bytes/block)
|
||||
├── DiskMetadataPage.bin (512 bytes/block)
|
||||
├── SpecialLogPage.bin (512 bytes/block)
|
||||
└── TelMesPages.log (40 bytes/record, 去除 null)
|
||||
```
|
||||
|
||||
### 特殊處理:TelMesPages.log (Page 0x64)
|
||||
|
||||
```java
|
||||
// 原始資料: 40 bytes/record,包含 null (0x00) 字元
|
||||
// 處理邏輯:
|
||||
// 1. 讀取每 40 bytes
|
||||
// 2. 跳過開頭的 null 字元
|
||||
// 3. 遇到換行符 (0x0a) 後,後續全部視為有效資料
|
||||
// 4. 輸出時每筆記錄加上換行符
|
||||
|
||||
// Example:
|
||||
// Input: [0x00, 0x00, 0x00, 0x31, 0x32, ..., 0x00, 0x00]
|
||||
// Output: "12...data\n"
|
||||
```
|
||||
|
||||
### Java 類別使用
|
||||
|
||||
```java
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.Calendar;
|
||||
|
||||
// 關鍵類別
|
||||
ZipOutputStream zout = new ZipOutputStream(fout);
|
||||
zout.setLevel(5); // 壓縮等級 (0=儲存, 9=最大壓縮)
|
||||
ZipEntry ze = new ZipEntry(filename);
|
||||
zout.putNextEntry(ze);
|
||||
zout.write(byte[] data);
|
||||
zout.closeEntry();
|
||||
zout.close();
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user