6

我用以下方式打开了一个文件:

fp = fopen("some.txt","r");

现在在这个文件中,第一个字节可以说 40 个字节是不必要的垃圾数据,所以我想删除它们。但是如果没有不必要的数据,我无法从该文件中删除该数据、修改或创建该文件的副本。

所以我想创建另一个指向文件的虚拟 FILE 指针,当我将此虚拟指针传递给执行以下操作的任何另一个函数时:

  fseek ( dummy file pointer , 0 , SEEK_SET );

那么它应该将文件指针设置在我的 some.txt 中的第 40 位。


但是该函数接受一个文件描述符,所以我需要传递一个文件描述符,它将文件视为前 40 个字节从未在文件中。


简而言之,虚拟描述符应该将文件视为那些 40 个字节不在该文件中,并且所有定位操作都应该相对于第 40 个字节计为第 1 个字节。

4

5 回答 5

4

简单的。

#define CHAR_8_BIT    (0)
#define CHAR_16_BIT   (1)
#define BIT_WIDTH     (CHAR_8_BIT)

#define OFFSET        (40)

FILE* fp = fopen("some.txt","r");
FILE* dummy = NULL;

#if (BIT_WIDTH == CHAR_8_BIT)
dummy = fseek (fp, OFFSET*sizeof(char), SEEK_SET);
#else
dummy = fseek (fp, OFFSET*sizeof(wchar_t), SEEK_SET);
#endif

宏指示文件的SEEK_SET开头,根据您使用的是 8 位字符 (ASCI) 还是 16 位字符(例如:UNICODE),您将从文件指针的开头向前步进 40 个字符,并分配该指针/地址到dummy.

祝你好运!

这些链接也可能会有所帮助:

char 与 wchar_t

http://www.cplusplus.com/reference/clibrary/cstdio/fseek/

如果需要,您可以通过 fdopen() 调用将文件描述符转换为文件指针。

http://linux.die.net/man/3/fdopen

于 2012-06-15T04:56:20.147 回答
2

如果您想删除磁盘上文件的前 40 个字节而不创建另一个文件,则可以将第 41 个字节及以后的内容复制到缓冲区中,然后在偏移量 -40 处将其写回。然后使用ftruncate(a POSIX library in unistd.h) 在 (filesize - 40) 偏移处截断。

于 2012-06-15T04:56:37.577 回答
2

fseek ( 虚拟文件指针 , 0 , SEEK_SET );

简而言之,虚拟指针应该将文件视为该文件中没有 40 个字节,并且所有位置都应该相对于第 40 个字节作为第 1 个字节计数。

你有冲突的要求,你不能用 C API 做到这一点。

SEEK_SET 总是指文件中的绝对位置,这意味着如果您希望该命令起作用,您必须修改文件并删除垃圾。

在 linux 上,您可以编写一个FUSE驱动程序来呈现文件,就像它从第 40 个字节开始一样,但这是很多工作。我之所以提到这一点,是因为它可以解决您创建的问题,但实际上这样做会很愚蠢。

当然,最简单的事情就是放弃您正在寻找的这个模拟层想法,并编写可以处理额外标题垃圾的代码。

于 2012-06-15T05:17:53.303 回答
1

我用我从你的问题中理解的内容写了一个小代码。

#include<stdio.h>

void readIt(FILE *afp)
{
    char mystr[100];
    while ( fgets (mystr , 100 , afp) != NULL )
       puts (mystr);
}
int main()
{
    FILE * dfp = NULL;
    FILE * fp = fopen("h4.sql","r");
    if(fp != NULL)
    {
        fseek(fp,10,SEEK_SET);
        dfp = fp;
        readIt(dfp);
        fclose(fp);
    }
}

readIt() 正在从 11 字节读取文件。这是你所期待的还是别的什么?

于 2012-06-15T04:53:01.237 回答
1

我实际上并没有尝试过,但我认为您应该能够使用mmap(使用 MAP_SHARED 选项)将文件映射到您的地址空间,然后fmemopen获得一个FILE*引用除前 40 个字节之外的所有字节的缓冲区.

这给了你一个FILE*(正如你在问题正文中描述的那样),但我相信不是文件描述符(如标题和问题的其他地方)。两者不一样,并且FILE*创建的AFAIKfmemopen没有关联的文件描述符。

于 2012-06-15T09:05:15.537 回答