2012-06-15 26 views
6

Tôi đã mở một tập tin với cách sau:Có cách nào để tạo bộ mô tả tệp giả trong linux không?

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

Bây giờ trong tập tin này ngày 1 số byte cho phép nói 40 byte là rác không cần thiết của dữ liệu vì vậy tôi muốn loại bỏ chúng. Nhưng tôi không thể xóa dữ liệu đó khỏi tệp đó, sửa đổi hoặc tạo các bản sao của tệp đó mà không có dữ liệu không cần thiết đó.

Vì vậy, tôi muốn tạo ra một con trỏ FILE giả mà chỉ vào tập tin và khi tôi vượt qua con trỏ giả này cho bất kỳ một chức năng nào hoạt động sau đây:

fseek (dummy file pointer , 0 , SEEK_SET); 

sau đó nó nên đặt con trỏ tập tin tại Vị trí thứ 40 trong some.txt của tôi.


Nhưng chức năng chấp nhận bộ mô tả tệp vì vậy tôi cần chuyển một bộ mô tả tệp sẽ coi tệp là 40 byte đầu tiên chưa bao giờ trong tệp.


Tóm lại, bộ mô tả giả nên xử lý tệp như 40 byte không có trong tệp đó và tất cả các hoạt động định vị phải liên quan đến byte thứ hai đó là byte thứ nhất.

+0

Kiểm tra bài đăng cập nhật bên dưới. – DevNull

+0

bạn có thể giải thích lại những gì bạn muốn không? chỉnh sửa của bạn âm thanh thực sự khó hiểu .. –

Trả lời

2

fseek (con trỏ tệp giả, 0, SEEK_SET);

Tóm lại, con trỏ giả nên xử lý tệp vì không có 40 byte đó trong tệp đó và tất cả vị trí phải tương ứng với byte thứ 40 đó khi được tính là byte thứ nhất.

Bạn có các yêu cầu xung đột, bạn không thể thực hiện điều này với API C.

SEEK_SET luôn đề cập đến vị trí tuyệt đối trong tệp, điều đó có nghĩa là nếu bạn muốn lệnh đó hoạt động, bạn phải sửa đổi tệp và xóa tệp rác.

Trên linux, bạn có thể viết trình điều khiển FUSE có thể hiển thị tệp như tệp bắt đầu từ byte thứ 40, nhưng đó là rất nhiều công việc. Tôi chỉ đề cập đến điều này bởi vì đó là có thể để giải quyết sự cố mà bạn đã tạo, nhưng sẽ rất ngớ ngẩn khi thực sự thực hiện việc này.

Điều đơn giản nhất của khóa học sẽ chỉ là từ bỏ ý tưởng lớp mô phỏng này mà bạn đang tìm kiếm và viết mã có thể xử lý thêm tiêu đề rác đó.

+0

bạn có vẻ đúng. trong linux để tạo ra mô tả tập tin giả như vậy tôi cần phải viết trình điều khiển của riêng tôi. bởi vì trong bất kỳ cách nào khác tôi không thể chenge tài sản của fd đầy đủ yêu cầu của tôi vì vậy bạn đang ngay bây giờ tôi cần phải suy nghĩ để xử lý rằng rác 40 byte .. !!! –

+0

Bạn không thể sử dụng fopencookie(), và có chức năng móc tùy chỉnh của bạn xử lý tất cả mọi thứ chính xác theo cách bạn muốn? – Collin

+0

Xin lỗi, không bao giờ. Đây là một phần mở rộng GNU không chuẩn. – Collin

1

Tôi đã viết một mã nhỏ với những gì tôi hiểu được từ câu hỏi của bạn.

#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() đang đọc tệp từ 11 byte. Đây có phải là điều bạn đang mong đợi hay điều gì khác không?

+0

fseek (dfp, 0, SEEK_SET); khi tôi sẽ làm điều đó sẽ luôn luôn đi vị trí thứ 0 không phải là vị trí thứ 40 kiểm tra mà .. !!! –

+0

Tôi không thử ... – Raghuram

4

Dễ dàng.

#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 

Các SEEK_SET vĩ mô chỉ ra đầu tệp, và tùy thuộc vào việc bạn đang sử dụng 8-bit ký tự (ASCI) hoặc các ký tự 16-bit (ví dụ: UNICODE), bạn sẽ bước 40 ký tự phía trước từ đầu của bạn con trỏ tệp và gán con trỏ/địa chỉ đó cho dummy.

Chúc may mắn!

Các liên kết này có thể sẽ rất hữu ích cũng như:

char vs wchar_t

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

Nếu bạn muốn, bạn chỉ có thể chuyển đổi một bộ mô tả tập tin vào một con trỏ tập tin thông qua fdopen() gọi.

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

+1

bạn dường như quên sử dụng OFFSET. –

+0

+1 ở trên; Cảm ơn; Mệt mỏi/muộn; Điểm tốt; Đã sửa lỗi – DevNull

+1

nhưng nếu sử dụng new_fd = fileno (giả); sau đó doesnt new_fd sẽ xử lý tập tin như nó đã được điều trị tập tin gốc? –

2

Nếu bạn muốn loại bỏ 40 byte đầu tiên của một tập tin trên đĩa mà không cần tạo tập tin khác, sau đó bạn có thể sao chép nội dung từ các byte lần thứ 41 trở đi vào một bộ đệm, sau đó viết nó lại bù đắp -40. Sau đó, sử dụng ftruncate (thư viện POSIX trong unistd.h) để cắt ngắn tại (filesize - 40) offset.

1

tôi đã không thực sự cố gắng này, nhưng tôi nghĩ rằng bạn sẽ có thể sử dụng mmap (với tùy chọn MAP_SHARED) để có được tập tin của bạn ánh xạ vào không gian địa chỉ của bạn, và sau đó fmemopen để có được một FILE* đó đề cập đến tất cả ngoại trừ 40 byte đầu tiên của bộ đệm đó.

Điều này cung cấp cho bạn FILE* (như bạn mô tả trong nội dung câu hỏi của mình), nhưng tôi tin rằng không phải là một bộ mô tả tệp (như trong tiêu đề và các nơi khác trong câu hỏi). Cả hai không giống nhau và AFAIK là FILE* được tạo với fmemopen không có bộ mô tả tệp được liên kết.

Các vấn đề liên quan