public static async Task CompressAsync(byte[] byteIn, Stream outStream) { using var stream = new ZlibStream(new MemoryStream(), CompressionMode.Compress, CompressionLevel.BestCompression); await stream.WriteAsync(byteIn, 0, byteIn.Length); await stream.CopyToAsync(outStream); }
public static async Task CompressAsync(Stream inputStream, Stream outputStream) { await using var stream = new ZlibStream(inputStream, CompressionMode.Compress, CompressionLevel.BestCompression); await stream.CopyToAsync(outputStream); }
static async Task ExtractSsf(FileInfo file, DirectoryInfo directory) { if (!file.Exists) { throw new FileNotFoundException(); // 找不到文件 } var buffer = new byte[1024]; // 准备一个buffer await using var fs = file.OpenRead(); // 打开文件 await fs.ReadAsync(buffer, 0, 4); // 先读它四个字节 switch (Encoding.ASCII.GetString(buffer, 0, 4)) { case "Skin": // 是加密的包 { // using语句不能直接在switch语句中使用 await using var data = new MemoryStream(); { fs.Seek(4, SeekOrigin.Current); // 跳过四个字节 await using var decrypted_ssfbin = new CryptoStream(fs, SsfAES.CreateDecryptor(), CryptoStreamMode.Read); // AES解码流 // 这个流不能Seek, 得想办法把它变成能Seek的流 await decrypted_ssfbin.ReadAsync(buffer, 0, 4); // 跳过四个字节, 这个流不能Seek 所以用读取4个字节的方式跳过 await using var tmps = new ZlibStream(decrypted_ssfbin, Ionic.Zlib.CompressionMode.Decompress); // 创建解压缩流解压缩文件 await tmps.CopyToAsync(data); // 把流中所有内容复制到可以Seek的流 data.Seek(0, SeekOrigin.Begin); // Seek! 设置指针在流开始的位置 } await data.ReadAsync(buffer, 0, 8); // 读取8个字节(两个uint) //var size = BitConverter.ToUInt32(buffer.ToArray(), 0);// 整体大小 uint[] offsets; { var offsets_length = BitConverter.ToInt32(buffer.ToArray(), 4); // 偏移信息长度 offsets = new uint[offsets_length / 4]; // 初始化偏移信息数组(一个uint长4byte) await data.ReadAsync(buffer, 0, offsets_length); // 将所有偏移信息一次读出来 for (int i = 0; i < offsets_length / 4; i++) // 计次循环 { offsets[i] = BitConverter.ToUInt32(buffer.ToArray(), i * 4); // 一个一个转换 } } directory.Refresh(); if (!directory.Exists) // 检查目录是否存在 { directory.Create(); // 不存在就创建一个 } foreach (var offset in offsets) // 遍历偏移数组 { data.Seek(offset, SeekOrigin.Begin); // Seek到偏移位置 string filename; // 文件名 { await data.ReadAsync(buffer, 0, 4); // 读取文件长度 var name_len = BitConverter.ToInt32(buffer.ToArray(), 0); if (buffer.Length < name_len) // 防止buffer小了塞冒出来 { buffer = new byte[name_len]; } await data.ReadAsync(buffer, 0, name_len); filename = Encoding.Unicode.GetString(buffer.ToArray(), 0, name_len); // 文件名是Unicode编码的 } await data.ReadAsync(buffer, 0, 4); // 读取内容长度 var content_len = BitConverter.ToInt32(buffer.ToArray(), 0); if (buffer.Length < content_len) // 防止buffer小了塞冒出来 { buffer = new byte[content_len]; } await data.ReadAsync(buffer, 0, content_len); // 这里读取的就是内容了 await using var outfs = new FileInfo(Path.Combine(directory.FullName, filename)).OpenWrite(); await outfs.WriteAsync(buffer, 0, content_len); // 写入数据 await outfs.FlushAsync(); // 流用完记得冲 } } break; case "\x50\x4b\x03\x04": // 这玩意是ZIP压缩包 ZipFile.ExtractToDirectory(file.FullName, directory.FullName); // 直接解压 break; default: // 是不认识的文件呢 throw new NotSupportedException(); } }