编写TAR文件头 - 需要验证

时间:2011-02-03 20:16:00

标签: .net format tar

在Windows上的.NET中,我尝试了几个开源tar库来编写tar存档(直接从内存中,输入文件实际上从未存在过)。

它们生成可以由tar库解析和提取的tar文件,但像7zip这样的程序报告tar是错误的。 Unix上的gtar也会抛出错误。

我没有在错误消息中收到任何特定的反馈,所以我不知道出了什么问题。

我曾尝试使用维基百科上的tar规范直接编写tar文件:http://en.wikipedia.org/wiki/Tar_(file_format),但这会产生相同的情况。

有没有人知道一个好的util可以验证并告诉我具体的tar文件有什么问题?

这是我编写档案的自定义代码。在归档结束时,我写了2 512个nul长度块作为终结符。请注意,此代码生成一个使用此开源库提取的存档:http://www.icsharpcode.net/opensource/sharpziplib/ 但就像我说的那样,对于unix上的7zip和gtar似乎无效。

public static void WriteTarEntry(string filename, byte[] data, Stream outputStream)
    {
        WriteTarEntryHeader(filename, data.Length, outputStream);
        WriteTarEntryData(data, outputStream);
    }
    static void WriteTarEntryHeader(string fileName, int fileSize, Stream outputStream)
    {
        var header = new byte[512];
        WriteStringToByteArray(fileName, header, 0, 100);
        WriteStringToByteArray(fileSize.ToString(), header, 124, 12);
        var unixTime = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
        WriteStringToByteArray(unixTime, header, 136, 12);
        WriteStringToByteArray("0", header, 156, 1);
        WriteStringToByteArray("ustar ", header, 257, 6);
        WriteStringToByteArray(" ", header, 263, 2);

        WriteStringToByteArray(Environment.UserName, header, 265, 32);
        WriteStringToByteArray(Environment.UserDomainName, header, 297, 32);

        WriteStringToByteArray("        ", header, 148, 8);
        var checksum =  Convert.ToString(header.Sum(b => b), 8).PadLeft(6, Char.Parse("0"));
        WriteStringToByteArray(checksum, header, 148, 6);
        header[148 + 6] = 0;
        header[148 + 7] = 32;
        outputStream.Write(header, 0, header.Length);
    }

    static void WriteStringToByteArray(string value, byte[] array, int start, int maxWidth)
    {
        var len = Math.Min(maxWidth, value.Length);
        var sourceBytes = Encoding.ASCII.GetBytes(value);
        Buffer.BlockCopy(sourceBytes, 0, array, start, len);
    }


    static void WriteTarEntryData(byte[] data, Stream outputStream)
    {
        int totalBytes = 0;
        while (totalBytes < data.Length)
        {
            totalBytes += 512;
        }
        var alldata = new byte[totalBytes];
        Buffer.BlockCopy(data, 0, alldata, 0, data.Length);
        outputStream.Write(alldata, 0, alldata.Length);
    }

1 个答案:

答案 0 :(得分:1)

好的 - 我设法解决了这个......我在这里发现了这篇文章:http://www.3dartist.com/WP/formats/index.html#tar

这提醒我,日期/时间和文件大小都必须在base-8中(我已经完成了校验和,但不是那两个)。

完成修复后,它可以正常工作。鉴于此错误,我很惊讶存档可以被开源库解析。

以下是更改的代码行:

static void WriteTarEntryHeader(string fileName, int fileSize, Stream outputStream)
    {
        var header = new byte[512];
        WriteStringToByteArray(fileName, header, 0, 100);
        WriteStringToByteArray(Convert.ToString(fileSize, 8), header, 124, 12);
        WriteStringToByteArray(0x1ff.ToString(), header, 100, 8);
        var unixTime = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds);
        WriteStringToByteArray(Convert.ToString(unixTime, 8), header, 136, 12);