В .NET в Windows я попробовал пару библиотек tar с открытым исходным кодом, чтобы написать архив tar (непосредственно из памяти, входные файлы никогда не существуют).
Они создают файлы tar, которые могут бытьанализируется и извлекается библиотеками tar, но программы, такие как 7zip, сообщают, что tar является ошибкой.Также gtar на Unix выбрасывает ошибки.
Я не получаю никакой обратной связи в сообщениях об ошибках, поэтому не знаю, что не так.
Я пытался писать файлы tar напрямую, используя спецификацию tar в Википедии: http://en.wikipedia.org/wiki/Tar_(file_format), но это приводит к той же ситуации.
Кто-нибудь знает о хорошем утилите, который может проверить и сказать мне конкретно, что не так с файлами tar, которые я генерирую?
Вот мой пользовательский код для написания архива.В конце архива я пишу 2 512 блоков длины nul в качестве терминатора.Обратите внимание, что этот код генерирует архив, который извлекает нормально с использованием этой библиотеки с открытым исходным кодом: http://www.icsharpcode.net/opensource/sharpziplib/, но, как я уже сказал, он кажется недопустимым для 7zip и gtar в unix.
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);
}