简体   繁体   English

有没有办法在linux中创建虚拟文件描述符?

[英]Is there any way to create dummy file descriptor in linux?

I have opened one file with following way: 我用以下方式打开了一个文件:

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

Now in this file the 1st some bytes lets say 40 bytes are unnecessary junk of data so I want to remove them. 现在在这个文件中,第一个字节可以说40个字节是不必要的数据垃圾,所以我想删除它们。 But I cannot delete that data from that file, modify or create duplicates of that file without that unnecessary data. 但我无法从该文件中删除该数据,修改或创建该文件的副本而没有那些不必要的数据。

So I want to create another dummy FILE pointer which points to the file and when I pass this dummy pointer to any another function that does the following operation: 所以我想创建另一个指向文件的虚拟FILE指针,当我将这个虚拟指针传递给执行以下操作的任何其他函数时:

  fseek ( dummy file pointer , 0 , SEEK_SET );

then it should set the file pointer at 40th position in my some.txt. 然后它应该将文件指针设置在some.txt中的第40个位置。


But the function accepts a file descriptor so i need to pass a file descriptor which will treat the file as those first 40 bytes were never in the file. 但是该函数接受一个文件描述符,所以我需要传递一个文件描述符,它将文件视为文件中从未出现的前40个字节。


In short that dummy descriptor should treat the file as those 40 bytes were not in that file and all positioning operations should be with respect to that 40th byte counting as the is 1st byte. 简而言之,虚拟描述符应该将文件视为那个40字节不在该文件中,并且所有定位操作应该相对于第40个字节计数为第1个字节。

Easy. 简单。

#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

The SEEK_SET macro indicates beginning of file, and depending on whether you are using 8-bit characters (ASCI) or 16-bit characters (eg: UNICODE) you will step 40 CHARACTERS forward from the beginning of your file pointer, and assign that pointer/address to dummy . SEEK_SET宏指示文件的开头,根据您使用的是8位字符(ASCI)还是16位字符(例如:UNICODE),您将从文件指针的开头向前步进40个CHARACTERS,并指定该指针/地址到dummy

Good luck! 祝好运!

These links will likely be helpful as well: 这些链接也可能会有所帮助:

char vs wchar_t char vs wchar_t

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

If you want, you can just convert a file descriptor to a file pointer via the fdopen() call. 如果需要,可以通过fdopen()调用将文件描述符转换为文件指针。

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

If you want to remove the first 40 bytes of a file on the disk without creating another file, then you can copy the content from the 41th byte and onwards into a buffer, then write it back at offset -40. 如果要删除磁盘上文件的前40个字节而不创建另一个文件,则可以将第41个字节中的内容复制到缓冲区中,然后将其写回offset -40。 Then use ftruncate (a POSIX library in unistd.h ) to truncate at (filesize - 40) offset. 然后使用ftruncateunistd.h的POSIX库)截断(filesize - 40)偏移量。

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

In short that dummy pointer should treat the file as there is no that 40 byte in that file and all position should be with respect to that 40th byte as counting as it is 1st byte. 简而言之,虚指针应该处理该文件,因为该文件中没有那个40字节,并且所有位置都应该相对于第40个字节计数,因为它是第1个字节。

You have conflicting requirements, you cannot do this with the C API. 您的要求存在冲突,您无法使用C API执行此操作。

SEEK_SET always refers to the absolute position in the file, which means if you want that command to work, you have to modify the file and remove the junk. SEEK_SET始终引用文件中的绝对位置,这意味着如果您希望该命令起作用,则必须修改该文件并删除垃圾。

On linux you could write a FUSE driver that would present the file like it was starting from the 40th byte, but that's a lot of work. 在linux上,您可以编写一个FUSE驱动程序,该文件将从第40个字节开始呈现文件,但这是很多工作。 I'm only mentioned this because it's possible to solve the problem you've created , but it would be quite silly to actually do this. 我只是提到这一点,因为它可以解决你创建的问题,但实际上这样做会很愚蠢。

The simplest thing of course would be just to abandon this emulating layer idea you're looking for, and write code that can handle that extra header junk. 最简单的事情当然是放弃你正在寻找的这个模拟层的想法,并编写可以处理额外的头垃圾的代码。

I wrote a small code with what i understood from your question. 我用你的问题理解我写了一个小代码。

#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);
    }
}

The readIt() is reading the file from the 11 byte. readIt()从11字节读取文件。 Is this what you are expecting or something else? 这是你期待的还是别的什么?

I haven't actually tried this, but I think you should be able to use mmap (with the MAP_SHARED option) to get your file mapped into your address space, and then fmemopen to get a FILE* that refers to all but the first 40 bytes of that buffer. 我实际上没有尝试过这个,但我认为你应该能够使用mmap (使用MAP_SHARED选项)将你的文件映射到你的地址空间,然后fmemopen得到一个FILE*引用除了前40个之外的所有FILE*该缓冲区的字节数。

This gives you a FILE* (as you describe in the body of your question), but I believe not a file descriptor (as in the title and elsewhere in the question). 这给你一个FILE* (正如你在问题正文中描述的那样),但我认为不是文件描述符(如标题和问题的其他部分)。 The two are not the same, and AFAIK the FILE* created with fmemopen does not have an associated file descriptor. 两者不一样,用fmemopen创建的AFAIK FILE*没有关联的文件描述符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM