Is there a way to create a dummy file descriptor on Linux?

I opened one file as follows:

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

Now in this file the first few bytes allow us to say that 40 bytes is an unnecessary data garbage, so I want to delete them. But I canโ€™t delete this data from this file, change or duplicate this file without extra data.

So, I want to create another dummy FILE pointer that points to a file, and when I pass this dummy pointer to any other function that performs the following operation:

  fseek ( dummy file pointer , 0 , SEEK_SET ); 

then it should set the file pointer to the 40th position in my some.txt.


But the function accepts a file descriptor, so I need to pass a file descriptor that will process the file, since the first 40 bytes were never in the file.


In short, this dummy descriptor must process the file, since these 40 bytes were not in this file, and all positioning operations should refer to this 40th byte count as 1st byte.

+6
source share
5 answers

fseek (file file pointer, 0, SEEK_SET);

In short, this dummy pointer should process the file, since this file should not contain 40 bytes, and all positions should refer to this 40th byte, considering it to be the 1st byte.

You have conflicting requirements, you cannot do this using API C.

SEEK_SET always refers to the absolute position in the file, which means that if you want this command to work, you need to modify the file and remove the garbage.

In linux, you can write a FUSE driver that will represent the file as if it started with the 40th byte, but this work, I mentioned this only because it is possible to solve the problem that you created, but it would actually be stupid doing so.

The easiest way, of course, would be to simply abandon the idea of โ€‹โ€‹the emulation layer you are looking for and write code that can handle this extra header garbage.

+2
source

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 the beginning of the file, and depending on whether you use 8-bit characters (ASCI) or 16-bit characters (for example, UNICODE), you perform step 40 CHARACTERS forward from the beginning of the file pointer and assign this pointer / address dummy .

Good luck

These links are also likely to be useful:

char vs wchar_t

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

If you want, you can simply convert the file descriptor to a file pointer through a call to fdopen ().

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

+4
source

If you want to delete the first 40 bytes of a file on disk without creating another file, you can copy the contents from the 41st byte to the buffer, and then write it back with an offset of -40. Then use ftruncate (the POSIX library in unistd.h ) to truncate with (file size 40).

+2
source

I wrote a little 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); } } 

ReadIt () reads a file from 11 bytes. Is this what you expect or something else?

+1
source

I have not actually tried this, but I think you should use mmap (with the MAP_SHARED option) to get the file mapped to your address space and then fmemopen to get FILE* this applies to all but the first 40 bytes of this buffers.

This gives you FILE* (as you describe in the body of your question), but I consider it not to be a file descriptor (both in the header and elsewhere in the question). The two options do not match, and the AFAIK FILE* created using fmemopen does not have an associated file descriptor.

+1
source

Source: https://habr.com/ru/post/918145/


All Articles