libarchive在提取文件时读取太多字符

时间:2010-05-21 14:58:09

标签: c malloc tar

我编写了一个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输出。对我来说这似乎是正确的。

我可以看到两种可能性,为什么我的输出不符合预期:

  1. 我犯了一个初学者的错误或
  2. 存档文件中的多字节字符与它有关。

2 个答案:

答案 0 :(得分:2)

我可能非常错了,但这看起来不像是以空字符结尾的字符串(我不认为archive_read_data负责这一点)。附加一个NULL字符或查看this并告诉我们它是怎么回事。

答案 1 :(得分:1)

我怀疑你不是正在阅读太多的字符,而只是打印太多了。

您正在使用%s说明符将文件内容输出到printf,它要求输入为以空字符结尾的字符串。存档中文件的内容可能不是以空值终止的,并且可能在中间包含任意空值。

尝试输出如下:

fwrite(fileContents, sizeof(char), entry_size, stdout);