首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 呼叫 J# 類庫實作 Zip 壓縮/解壓縮:跨語言互通實戰指南

     編輯:關於C語言

為什麼需要 J# 類庫?

.NET Framework 早期版本內建無 Zip 壓縮類別。雖有第三方庫(如 SharpZipLib),但穩定度與授權皆有考量。J# 實作了 JDK 1.1.4 的 java.util.zip 命名空間,透過 .NET 語言互通性(CLS),C# 可直接引用 J# 組件 vjslib.dll 使用成熟的 Java 壓縮 API。

環境建置步驟

  1. 下載安裝 J# 1.0 Redistributable Package(無需完整 Visual J#)。
  2. 專案加入參考:C:\WINDOWS\Microsoft.NET\Framework\v1.0.4205\vjslib.dll(路徑視 Windows 目錄而定)。
  3. 物件瀏覽器即可檢視 java.util.zip 命名空間類別。

核心類別對照表

Java 類別用途
java.util.zip.ZipFile讀取現有 Zip 檔案、列舉條目
java.util.zip.ZipEntry單一壓縮條目資訊(檔名、大小、CRC、壓縮方法等)
java.util.zip.ZipOutputStream建立/寫入 Zip 檔案
java.util.zip.Deflater / Inflater低層級資料壓縮/解壓縮(非檔案層級)

關鍵技術細節:Java 與 .NET 列舉器差異

Java Enumeration 與 .NET IEnumerator 行為不同:

  • Java:nextElement() 同時「取得目前元素」並「移至下一個」
  • .NET:MoveNext() 移至下一個,Current 取得目前元素
  • Java 無 Reset() 方法,無法重新列舉

解決方案:撰寫 EnumerationAdapter 實作 IEnumerable,封裝 Java 列舉器,支援 C# foreach。

解壓縮 Zip 檔案實作要點

// 取得輸入串流
InputStream input = zipFile.getInputStream(entry);

// 複製到檔案
FileOutputStream output = new FileOutputStream(targetPath);
CopyStream(input, output);  // 自訂輔助方法

// 目錄結構處理:ZipEntry 包含完整路徑,需自行建立子目錄
if (entry.isDirectory()) continue;  // 略過目錄條目
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));

注意:不支援密碼保護,若需加密請使用 System.Security.Cryptography 自行實作(產生的檔案將不相容 WinZip 等標準工具)。

建立/修改 Zip 檔案

Java Zip API 不支援隨機存取,修改(新增/刪除條目)需:

  1. 建立新的 ZipOutputStream 寫入暫存檔
  2. 遍歷原 Zip 條目,解壓縮後重新壓縮寫入新檔
  3. 新增條目時呼叫 putNextEntry() 並寫入資料
  4. 完成後以新檔取代舊檔

壓縮方法常數:ZipEntry.DEFLATED(壓縮)、ZipEntry.STORED(僅儲存)。

低層級資料壓縮:字串壓縮範例

// 壓縮字串
public static byte[] CompressString(string text)
{
    var deflater = new java.util.zip.Deflater(compressionLevel);
    deflater.setInput(JavaStructMarshalHelper.convertToByteArray(text));
    deflater.finish();
    
    var bos = new java.io.ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    while (!deflater.finished())
    {
        int count = deflater.deflate(buffer);
        bos.write(buffer, 0, count);
    }
    return bos.toByteArray();
}

// 解壓縮字串
public static string DecompressString(byte[] data)
{
    var inflater = new java.util.zip.Inflater();
    inflater.setInput(data);
    
    var bos = new java.io.ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    while (!inflater.finished())
    {
        int count = inflater.inflate(buffer);
        bos.write(buffer, 0, count);
    }
    return JavaStructMarshalHelper.convertToString(bos.toByteArray());
}

關鍵點:Java byte 為有號數,J# 使用 sbyte;透過 com.ms.vJSharp.struct.JavaStructMarshalHelper 轉換陣列。

J# 運行庫其他高價值功能

1. Win32 API 存取(J/Direct)

com.ms.win32 命名空間提供 User32、Kernel32、Gdi32 等核心 API。常數定義在 winX 介面(如 wins.SW_SHOW)。

因介面含欄位不符 CLS,C# 編譯器無法直接存取,需用反射:

private int GetWin32Constant(string name)
{
    var asm = Assembly.GetAssembly(typeof(com.ms.win32.wina));
    var type = asm.GetType("com.ms.win32.win" + char.ToLower(name[0]), true);
    var field = type.GetField(name);
    return int.Parse(field.GetValue(null).ToString());
}

2. 高精度數學運算

java.math.BigDecimal、BigInteger 支援任意精度數值運算,適用加密演算法、科學計算。可包裝為 C# 友善型別並多載運算子。

部署考量

  • 目標機器需安裝 .NET Framework + J# Redistributable。
  • 不支援 .NET Compact Framework(智慧型裝置),無法用於 Windows CE/Mobile 專案。
  • Web 應用程式(含 Mobile Web Controls)可正常使用。
  • 組件複製到本機目錄(Copy Local)無效,因 J# 組件強依賴原生呼叫。

結論

J# 運行庫提供免費、微軟官方支援、功能完整的 Zip 壓縮、Win32 API、高精度數學等功能,是 .NET 早期版本缺乏這些功能時的最佳補完方案。即使現代 .NET 已內建 System.IO.Compression,理解跨語言互通機制仍具架構參考價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved