我已按以下方式打开一个文件:
fp = fopen("some.txt","r");
现在在这个文件中第1个字节可以说40个字节是不必要的数据垃圾,所以我想删除它们。但我无法从该文件中删除该数据,修改或 在没有不必要的数据的情况下创建该文件的副本。
所以我想创建另一个指向文件的虚拟FILE指针,当我将这个虚拟指针传递给执行以下操作的任何其他函数时:
fseek ( dummy file pointer , 0 , SEEK_SET );
然后它应该将文件指针设置在my.txt中的第40个位置。
但该函数接受一个文件描述符,所以我需要传递一个文件描述符,该文件描述符将文件处理为前40个字节从不在文件中。
简而言之,虚拟描述符应该将文件视为那个40字节不在该文件中,并且所有定位操作都应该相对于第40个字节计数为第1个字节。
答案 0 :(得分: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
。
这些链接也可能会有所帮助:
http://www.cplusplus.com/reference/clibrary/cstdio/fseek/
如果需要,可以通过fdopen()调用将文件描述符转换为文件指针。
答案 1 :(得分:2)
如果要删除磁盘上文件的前40个字节而不创建另一个文件,则可以将第41个字节中的内容复制到缓冲区中,然后将其写回偏移量-40。然后使用ftruncate
(unistd.h
中的POSIX库)截断(文件大小 - 40)偏移量。
答案 2 :(得分:2)
fseek(虚拟文件指针,0,SEEK_SET);
简而言之,虚指针应该处理该文件,因为该文件中没有那个40字节,并且所有位置都应该相对于第40个字节计算,因为它计算的是第1个字节。
您的要求存在冲突,您无法使用C API执行此操作。
SEEK_SET始终引用文件中的绝对位置,这意味着如果您希望该命令起作用,则必须修改该文件并删除垃圾。
在Linux上,您可以编写一个FUSE驱动程序,该驱动程序将显示文件,就像它从第40个字节开始一样,但是很多的工作。我只是提到了这个,因为可能来解决你已经创建的问题,但实际上这样做真是太傻了。
最简单的事情当然是放弃你正在寻找的这个模拟层的想法,并编写可以处理额外标题垃圾的代码。
答案 3 :(得分: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字节读取文件。 这是你期待的还是别的什么?
答案 4 :(得分:1)
我实际上没有尝试过这个,但我认为你应该可以使用mmap
(使用MAP_SHARED选项)将文件映射到你的地址空间,然后fmemopen
来获取一个FILE*
引用该缓冲区的前40个字节以外的所有字节。
这会给你一个FILE*
(正如你在问题正文中描述的那样),但我相信不是一个文件描述符(如标题和问题的其他部分所述)。两者不一样,使用FILE*
创建的fmemopen
AFAIK没有关联的文件描述符。