3

我想知道是否有人可以推荐一种工具来分析压缩文件或任何存档文件。我的意思不是检查档案里面有什么,而是更多关于它是如何被压缩的,用什么压缩方法等等。

谢谢!

4

2 回答 2

3

对于压缩到 ZIP 文件中的数据,命令行工具zipinfo非常有用,尤其是在使用“-v”参数时(用于详细模式)。我从 SuperUser 上的这个与 zip 相关的问题中了解到 zipinfo

于 2013-08-22T01:13:20.933 回答
1

我最近遇到了一个问题,即由一个工具创建的 zip 只能用某些程序打开,而不能用其他程序打开。问题原来是目录在 zip 文件中没有条目,它们只是由其中存在的文件暗示。此外,所有目录分隔符都是反斜杠而不是正斜杠。

zipinfo 对这些位并没有真正的帮助。我需要查看 zip 条目,所以我最终写了以下内容,这使我可以将目录条目与已知的好版本进行比较

using System;
using System.IO;
using System.Text;

namespace ZipAnalysis
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("No filename specified");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey(true);
                return;
            }
            string fileName = args[0];
            if (!File.Exists(fileName))
            {
                Console.WriteLine($"File not found: {fileName}");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey(true);
                return;
            }

            using (var file = File.OpenRead(fileName))
            {
                //First, find the End of central directory record

                BinaryReader reader = new BinaryReader(file);
                int entryCount = ReadEndOfCentralDirectory(reader);
                if (entryCount > 0)
                {
                    ReadCentralDirectory(reader, entryCount);
                }
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey(true);
        }

        private static int ReadEndOfCentralDirectory(BinaryReader reader)
        {
            var b = reader.ReadByte();
            int result = 0;
            long fileSize = reader.BaseStream.Length;
            while (result == 0 && reader.BaseStream.Position < fileSize)
            {
                while (b != 0x50)
                {
                    if (reader.BaseStream.Position < fileSize)
                        b = reader.ReadByte();
                    else
                        break;
                }

                if (reader.BaseStream.Position >= fileSize)
                {
                    break;
                }

                if (reader.ReadByte() == 0x4b && reader.ReadByte() == 0x05 && reader.ReadByte() == 0x06)
                {
                    int diskNumber = reader.ReadInt16();
                    int centralDirectoryStartDiskNumber = reader.ReadInt16();
                    int centralDirectoryCount = reader.ReadInt16();
                    int centralDirectoryTotal = reader.ReadInt16();
                    result = centralDirectoryTotal;
                    int centralDirectorySize = reader.ReadInt32();
                    int centralDirectoryOffset = reader.ReadInt32();
                    int commentLength = reader.ReadInt16();
                    string comment = Encoding.ASCII.GetString(reader.ReadBytes(commentLength));
                    Console.WriteLine("EOCD Found");
                    Console.WriteLine($"Disk Number: {diskNumber}");
                    Console.WriteLine($"Central Directory Disk Number: {centralDirectoryStartDiskNumber}");
                    Console.WriteLine($"Central Directory Count: {centralDirectoryCount}");
                    Console.WriteLine($"Central Directory Total: {centralDirectoryTotal}");
                    Console.WriteLine($"Central Directory Size: {centralDirectorySize}");
                    Console.WriteLine($"Central Directory Offset: {centralDirectoryOffset}");
                    Console.WriteLine($"Comment: {comment}");
                    reader.BaseStream.Seek(centralDirectoryOffset, SeekOrigin.Begin);
                }
            b=0;
            }
            return result;
        }

        private static void ReadCentralDirectory(BinaryReader reader, int count)
        {
            for (int i = 0; i < count; i++)
            {
                var signature = reader.ReadInt32();
                if (signature == 0x02014b50)
                {
                    Console.WriteLine($"Version Made By: {reader.ReadInt16()}");
                    Console.WriteLine($"Minimum version to extract: {reader.ReadInt16()}");
                    Console.WriteLine($"Bit Flag: {reader.ReadInt16()}");
                    Console.WriteLine($"Compression Method: {reader.ReadInt16()}");
                    Console.WriteLine($"File Last Modification Time: {reader.ReadInt16()}");
                    Console.WriteLine($"File Last Modification Date: {reader.ReadInt16()}");
                    Console.WriteLine($"CRC: {reader.ReadInt32()}");
                    Console.WriteLine($"CompressedSize: {reader.ReadInt32()}");
                    Console.WriteLine($"UncompressedSize: {reader.ReadInt32()}");
                    var fileNameLength = reader.ReadInt16();
                    var extraFieldLength = reader.ReadInt16();
                    var fileCommentLength = reader.ReadInt16();
                    Console.WriteLine($"Disk number where file starts: {reader.ReadInt16()}");
                    Console.WriteLine($"Internal file attributes: {reader.ReadInt16()}");
                    Console.WriteLine($"External file attributes: {reader.ReadInt32()}");
                    Console.WriteLine($"Relative offset of local file header: {reader.ReadInt32()}");
                    string filename = Encoding.ASCII.GetString(reader.ReadBytes(fileNameLength));
                    string extraField = Encoding.ASCII.GetString(reader.ReadBytes(extraFieldLength));
                    string fileComment = Encoding.ASCII.GetString(reader.ReadBytes(fileCommentLength));
                    Console.WriteLine($"Filename: {filename}");
                    Console.WriteLine($"Extra Field: {extraField}");
                    Console.WriteLine($"File Comment: {fileComment}");
                }
            }
        }
    }
}
于 2018-08-15T13:55:18.170 回答