2010-08-18 37 views
5

Khi cố gắng để sao chép một tập tin văn bản từ A đến một tập tin B, có thể có một số phương pháp: 1) byte bởi byte 2) từng chữ 3) từng dòngLàm cách nào để sao chép tệp văn bản trong C hoặc C++?

cái nào là hiệu quả hơn?

+4

Bạn quên bộ đệm theo bộ đệm. Các luồng C và C++ đã được đệm (kích thước liên quan đến hệ thống tệp hệ điều hành). Sử dụng công cụ này để sao chép các khối có kích thước tối ưu gần. –

Trả lời

18

Sử dụng bộ đệm:

#include <fstream> 

int main() 
{ 
    std::ifstream inFile("In.txt"); 
    std::ofstream outFile("Out.txt"); 

    outFile << inFile.rdbuf(); 
} 

C++ fstreams được đệm trong nội bộ. Họ sử dụng một kích thước bộ đệm hiệu quả (mặc dù những gì mọi người nói về hiệu quả của dòng :-). Vì vậy, chỉ cần sao chép một bộ đệm luồng vào một luồng và hey ưu tiên ma thuật bên trong sẽ làm một bản sao hiệu quả của một luồng đến một luồng khác.

Nhưng học cách làm điều đó char bằng char sử dụng std :: copy() thú vị hơn rất nhiều.

+0

Tuyệt vời nhất. Cảm ơn. – user373215

+0

Danh tiếng của Iostreams về sự không hiệu quả đến từ định dạng I/O; để bung các byte thô xung quanh như thế này, nó tốt bằng mọi thứ có thể. –

+0

rdbuf() không rdBuf() –

4

Chỉ cần "đệm theo bộ đệm", sao chép tệp ở chế độ nhị phân và đọc/ghi các phần X byte dài. Tôi nghĩ rằng giải pháp nhanh nhất là chỉ cần sử dụng chức năng sao chép của chính ngôn ngữ C hoặc gọi hệ thống.

Bộ đệm lớn nhất sẽ cung cấp cho bạn ít HDD tìm kiếm hoạt động dữ liệu hơn (sao chép nhanh hơn) nhưng sử dụng RAM nhiều hơn.

0

Nếu được thực hiện tốt, Byte by byte sẽ hiệu quả hơn. Tất nhiên đó không phải là toàn bộ câu chuyện: nó phụ thuộc vào bao nhiêu byte bạn sao chép cùng một lúc. Nếu bạn theo nghĩa đen sao chép byte cho byte, bạn sẽ thực hiện một cuộc gọi I/O cho mỗi byte và kết thúc chậm hơn so với các thư viện chuỗi. Hầu hết mọi người chỉ đoán ở một kích thước bộ đệm tốt (thường là 2048 hoặc lớn hơn, trong bội số của 2) và sử dụng nó.

+0

Bạn có thể giải thích cơ chế cơ bản của việc đoán ở kích thước bộ đệm tốt? – user297850

+0

Tùy thuộc vào loại tệp văn bản trung bình của bạn được lưu trữ, bạn có thể có các sector 512 byte (nhiều ổ cứng truyền thống) hoặc 2048 byte (đĩa quang, nhiều thiết bị bộ nhớ trạng thái rắn, một số ổ cứng mới hơn) , v.v.) Để giảm thiểu công việc mà ổ đĩa của bạn phải làm, bạn muốn sao chép trong bội số của một sector.Do đó, bạn có thể sao chép 2048 byte tại một thời điểm, với các hoạt động được liên kết với ranh giới 2048 byte (hoặc thay thế bất kỳ bội số nào của 2K cho 2048). – bta

+1

Nói chung, tùy chọn tốt nhất là sử dụng nhiều trang bộ nhớ. Trong linux, tôi tin rằng mặc định là 4K. Trình quản lý bộ nhớ ảo rất tốt để tối ưu hóa phần còn lại cho bạn, vì vậy việc đọc/ghi một trang tại một thời điểm có thể khá nhanh. Sử dụng kích thước bộ đệm lớn hơn có thể tốt hơn vì ít syscalls cần thiết (tất cả các syscalls có trên đầu) và có lẽ đĩa cứng đệm (không có đảm bảo mặc dù tập tin của bạn sẽ được trong các lĩnh vực liên tục trên ổ đĩa anyway). Nó phụ thuộc. – wds

-2

Tôi thực sự phải tự làm điều tương tự một lần, vì vậy tôi đã hẹn giờ với nhiều kích cỡ khác nhau. Những gì tôi tìm thấy là, cho một tập tin lớn, thời gian thực hiện gần như hoàn toàn là một chức năng của bao nhiêu I/O của tôi thực hiện (bất kể kích thước của chúng).

Vì vậy, đặt cược tốt nhất của bạn là thực hiện càng ít I/O càng tốt. Tốt nhất là hai (một để đọc và một để viết).

0

Nếu bạn thực hiện từng từ hoặc từng dòng, bạn khó có thể tái tạo lại tệp gốc vì có nhiều dạng ngắt dòng (\ r, \ n, \ r \ n) và dấu cách (\ p, \ f, 0x32) được nhúng trong các tệp văn bản mà bạn đang mạo hiểm bị mất theo cách này.

Cách hiệu quả nhất để sao chép tệp là sử dụng bộ đệm byte. Bộ đệm càng lớn thì sao chép càng hiệu quả, miễn là kích thước bộ đệm của bạn không lớn hơn kích thước bộ đệm trong đĩa cứng (ngày nay chủ yếu là ~ 8mb).

0

Hãy thử sử dụng C++ iostream và STL. Dưới đây là một ví dụ:

ifstream infile("to_copy.txt"); 
if (infile) 
{ 
    istreambuf_iterator<char> ifit(infile); 
    ofstream outfile("the_copy.txt"); 
    ostreambuf_iterator<char> ofit(outfile); 
    if (outfile) 
    { 
     copy(ifit, istreambuf_iterator<char>(), ofit); 
     outfile.close(); 
    } 
    else 
    { 
     cerr << "Could not open output file" << "\n"; 
    } 
    infile.close(); 
} 
else 
{ 
    cerr << "Could not open input file" << "\n"; 
} 

Note: điều này có thể không phù hợp trong mọi tình huống. Sử dụng/điều chỉnh tùy thuộc vào các yêu cầu cụ thể của bạn (ví dụ: các tệp thông thường hoặc humongous).

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