我正在编写一个小的C#appx包编辑器(appx基本上是一个包含一堆XML元数据文件的zip文件)。
为了制作有效的appx文件,我需要创建一个块映射文件(XML),其中包含每个文件的两个属性:散列和大小,如此处所述(https://docs.microsoft.com/en-us/uwp/schemas/blockmapschema/element-block)
Hash表示文件的64kb未压缩块。大小表示压缩后该块的大小(deflate算法)。以下是我到目前为止所写的概念证明:
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace StreamTest
{
class Program
{
static void Main(string[] args)
{
using (var srcFile = File.OpenRead(@"C:\Test\sample.txt"))
{
ZipAndHash(srcFile);
}
Console.ReadLine();
}
static void ZipAndHash(Stream inStream)
{
const int blockSize = 65536; //64KB
var uncompressedBuffer = new byte[blockSize];
int bytesRead;
int totalBytesRead = 0;
//Create a ZIP file
using (FileStream zipStream = new FileStream(@"C:\Test\test.zip", FileMode.Create))
{
using (ZipArchive zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create))
{
using (BinaryWriter zipWriter = new BinaryWriter(zipArchive.CreateEntry("test.txt").Open()))
{
//Read stream with a 64kb buffer
while ((bytesRead = inStream.Read(uncompressedBuffer, 0, uncompressedBuffer.Length)) > 0)
{
totalBytesRead = totalBytesRead + bytesRead;
//Compress current block to the Zip entry
if (uncompressedBuffer.Length == bytesRead)
{
//Hash each 64kb block before compression
hashBlock(uncompressedBuffer);
//Compress
zipWriter.Write(uncompressedBuffer);
}
else
{
//Hash remaining bytes and compress
hashBlock(uncompressedBuffer.Take(bytesRead).ToArray());
zipWriter.Write(uncompressedBuffer.Take(bytesRead).ToArray());
}
}
//How to obtain the size of the compressed block after invoking zipWriter.Write() ?
Console.WriteLine($"total bytes : {totalBytesRead}");
}
}
}
}
private static void hashBlock(byte[] uncompressedBuffer)
{
// hash the block
}
}
}
我可以在阅读流时使用64kb缓冲区轻松获取哈希属性,我的问题是:
使用zipWrite.Write()之后如何获取每个64kb块的压缩大小,是否可以使用System.IO.Compression或者我应该使用其他东西?
答案 0 :(得分:0)
如果您的问题仍然存在,那么对于创建容器,您可以使用2种方法:
为了即时获取块压缩大小,您可以使用DeflateStream和MemoryStream,如下所示:
class chararithdemo {
public static void main(String[] args) {
char ch ;
for ( ch = 85; ch = 90; ch++){
System.out.println( " ch is now : " + ch);
}
}
}
获取块大小和哈希的解决方案:
IAppxBlockMapBlock接口提供一个只读对象,该对象表示App包的块映射文件(AppxBlockMap.xml)中包含的文件中的单个块。 IAppxBlockMapFile :: GetBlocks方法用于返回一个枚举器,用于遍历和检索包块映射中列出的文件的各个块。
IAppxBlockMapBlock接口继承自IUnknown接口并具有以下方法:
GetCompressedSize - 检索块的压缩大小。
GetHash - 检索块的哈希值。