我编写了一个C程序,使用libarchive从tar存档中提取文件。
我想从此存档中提取文件并将其打印到标准输出。 但我得到了额外的字符。它是垃圾,但它来自另一个文件(可能在存档中与它相邻)。我希望输出结束于</html>
。
以下是阅读this tar file的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "archive.h"
#include "archive_entry.h"
int main (int argc, const char * argv[])
{
struct archive *a;
struct archive_entry *entry;
int r;
int64_t entry_size;
a = archive_read_new();
archive_read_support_compression_none(a);
archive_read_support_format_tar(a);
r = archive_read_open_filename(a, "0000.tar", 1024);
if (r != ARCHIVE_OK)
{
printf("archive not found");
}
else
{
while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
{
const char *currentFile = archive_entry_pathname(entry);
char *fileContents;
entry_size = archive_entry_size(entry); //get the size of the file
fileContents = malloc(entry_size); //alloc enough for string - from my testing I see that this is how many bytes tar and ls report from command line
archive_read_data(a, fileContents, entry_size); //read data into fileContents string for the HTML file size
if(strcmp(currentFile, "vendar-definition.html") == 0)
{
printf("file name = %s, size = %lld\n", currentFile, entry_size);
printf("%s\n\n", fileContents); //this output over-reads chars from another file in this tar file
}
free(fileContents); //free the C string because I malloc'd
}
}
printf("exit");
return 0;
}
libarchive 2.8.3在mac os X 10.6.3上编译。 gcc 4.2 x86_64
ls -l vendar-definition.html
为我提供1921
文件大小。所以显示tar tfv 0000.tar | grep vendar-definition.html
。因此报告说明文件大小的C输出。对我来说这似乎是正确的。
我可以看到两种可能性,为什么我的输出不符合预期:
答案 0 :(得分:2)
我可能非常错了,但这看起来不像是以空字符结尾的字符串(我不认为archive_read_data
负责这一点)。附加一个NULL字符或查看this并告诉我们它是怎么回事。
答案 1 :(得分:1)
我怀疑你不是正在阅读太多的字符,而只是打印太多了。
您正在使用%s
说明符将文件内容输出到printf
,它要求输入为以空字符结尾的字符串。存档中文件的内容可能不是以空值终止的,并且可能在中间包含任意空值。
尝试输出如下:
fwrite(fileContents, sizeof(char), entry_size, stdout);