2009-02-25 28 views
12

Tôi đang sử dụng fopen fseeko64 ftello64 ​​fclose vv để hoạt động trên một tệp.Cắt tệp

Tôi làm cách nào để cắt bớt tệp? Tôi biết rằng không có cách tiêu chuẩn để làm điều này trong C. Tất cả tôi muốn là một số cách mà sẽ làm việc trên bất kỳ nền tảng win32. Tôi đang sử dụng mingw gcc để biên dịch.

Xin lưu ý: Tôi muốn cắt kích thước của tệp theo kích thước được chỉ định, không làm cho kích thước đó ở 0. Và sử dụng một mẹo như sao chép một phần vào một tập tin khác và xóa/đổi tên là không thích hợp.

+0

Bạn có nghĩa là cắt ngắn tại một vị trí cụ thể hoặc cắt ngắn thành tệp trống không? – paxdiablo

+0

có thể ** trùng lặp ** của ** [Cách cắt ngắn một tệp trong C?] (Http://stackoverflow.com/a/873653/2432317) ** –

Trả lời

5

Nếu bạn muốn cắt file để kích cỡ bằng không, bạn có thể fopen với "w" cờ:

FILE *fh = fopen("file.txt","w"); 
if (fh != NULL) fclose(fh); 

Đối với cắt bỏ đến một kích thước cụ thể trong tiêu chuẩn C, bạn có thể làm điều này với giải pháp chuyển/đổi tên, chẳng hạn như:

FILE *finp = fopen ("inp.txt", "rb");  // should check for NULLs 
FILE *fout = fopen ("out.txt", "wb"); 

size_t sz = 100000;       // 100,000 bytes 
char *buff = malloc (sz);     // should check for NULL 

sz = fread (buff, 1, sz, fin);    // should check for errors 
fwrite (buff, 1, sz, fout); 

free (buff); 

fclose (fin); 
fclose (fout); 

rename ("out.txt", "inp.txt);    // should check for error 

Tất nhiên, nếu bạn có quyền truy cập vào tiêu đề và thư mục Win32 Ries (và tôi tin rằng MinGW cung cấp cho bạn điều này), bạn có thể sử dụng SetEndOfFile(), vì nó thực hiện tại chỗ, thay vì phải tạo một tệp mới và sau đó đổi tên nó.

Điều đó có nghĩa là sử dụng tệp dựa trên xử lý Windows I/O thay vì C FILE* dựa trên nhưng, nếu bạn đang giới hạn bản thân với Windows, điều đó có thể không quan trọng. Nếu bạn muốn tính di động, mặt khác, bạn sẽ cần một giải pháp dựa trên tiêu chuẩn C, chẳng hạn như giải pháp chuyển/đổi tên ở trên.

+1

Tại sao bạn sử dụng một con trỏ đến một ký tự đơn? Bạn có thể sử dụng fgetc() và fputc() và chỉ sử dụng một non-pointer (hoặc thậm chí không phải là một biến): for (int i = 0; i <100000; i ++) fputc (fgetc (vây), fout); –

+0

Điều này sẽ dẫn đến 100.000 lần nhiều cuộc gọi hàm :-) – paxdiablo

+0

Ah, có một số sự hiểu lầm. Lấy làm tiếc. (Tuy nhiên, tôi không nghĩ rằng 100000 fgetc() s và fputc() s thực sự mất nhiều thời gian.) –

17

SetEndOfFile()

Lấy một handle của tập tin với quyền truy cập ghi, đặt con trỏ tập tin, sau đó gọi SetEndOfFile().

-Adam

+1

Thật không may là không giải thích cách chuyển đổi giá trị FILE * OP thành một HANDLE phù hợp để chuyển đến SetEndOfFile() – Malvineous

+0

Bên cạnh những gì đã được đề cập trong phần bình luận (http://stackoverflow.com/questions/584639/truncate-file#comment9468490_584647) bởi [@Malvineous] (http://stackoverflow.com/users/308237/malvineous)… Tôi muốn lưu ý rằng bạn đang chỉ đến một hàm *** C++ ***, trong khi OP hỏi về *** C *** và đã gắn thẻ câu hỏi một cách rõ ràng với *** C *** tương ứng. –

1

Như đã đề cập, bạn có thể sử dụng fopen() với cờ "w" như:

FILE *f = fopen("file.txt", "w"); 

Ngoài ra, nếu bạn đã có file mở ra, bạn có thể sử dụng chức năng freopen(), một lần nữa với cờ "w":

FILE *f = fopen("file.txt", "r"); //initial fopen() call 
... 
f = freopen("file.txt", "w", f); //reopens "file.txt" and truncates it 

http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html

EDIT: Sau khi nhìn thấy bạn đã chỉnh sửa OP của bạn, tôi sẽ không repost những gì Pax và Adam Davis đã đặt. Ngoài ra, tôi sẽ xác nhận những gì Pax nói, rằng MinGW không cung cấp cho bạn quyền truy cập vào các tiêu đề Win32.

4

Đối với các thao tác tệp dựa trên FILE, hãy sử dụng _fileno() và _chsize_s() để thay đổi kích thước của tệp.

int changesize(FILE *fp, __int64 size) 
{ 
    int filedes = _fileno(fp); 
    return _chsize_s(filedes, size); 
} 

Một phiên bản truncate có thể được viết bằng xác nhận rằng kích thước được cung cấp nhỏ hơn kích thước tập tin hiện nay, như _chsize_s() sẽ cắt ngắn hoặc mở rộng kích thước của một tập tin - xem http://msdn.microsoft.com/en-us/library/whx354w1(VS.80).aspx.

+0

Giả sử bạn có quyền truy cập vào thời gian chạy của Microsoft. –