在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);
}
答案 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);