2009-06-25 33 views
5

Có cách nào để ghép nối hai luồng (hoặc tập tin mô tả) với nhau để ghi vào một luồng cũng sẽ ghi vào luồng thứ hai không? (C, Linux)Viết đồng thời hai luồng

Cảm ơn.

Trả lời

1

Tên người dùng là chính xác, nhưng trên Linux, chức năng bạn đang tìm kiếm được gọi là fopencookie. Ví dụ sửa laalto cho Linux dẫn:

int my_writefn(void *cookie, const char *data, int n) { 
    FILE **files = (FILE **)cookie; 
    fwrite(data, n, 1, files[0]); 
    return fwrite(data, n, 1, files[1]); 
} 

int noop(void) { return 0; } 
cookie_io_functions_t my_fns = { 
    (void*) noop, 
    (void*) my_writefn, 
    (void*) noop, 
    (void*) noop 
}; 

FILE *files[2] = ...; 

FILE *f = fopencookie((void *)files, "w", my_fns); 

// ... use f as you like ... 

Khi bạn viết thư cho f, hệ thống sẽ thực hiện chức năng my_writefn bạn đi qua nó là dữ liệu đã được truyền cho fwrite. Để làm cho mọi việc dễ dàng hơn, bạn cũng có thể muốn thay đổi đệm cho dòng tập tin của bạn phải được định hướng dòng:

setvbuf(f, NULL, _IOLBF, 0); 

Đó sẽ đệm lưu dữ liệu truyền cho fwrite cho đến khi một dòng mới là sản lượng hoặc bất kỳ dữ liệu được đọc từ bất kỳ luồng được gắn với các quy trình (ví dụ: stdin). LƯU Ý: bạn phải gọi sevbuf sau fopencookie nhưng trước khi bất kỳ dữ liệu nào được ghi vào luồng.

Tôi sử dụng bộ đệm đường vì tôi thường sử dụng fopencookie để chuyển hướng stderr tới nhật ký hệ thống, hoặc qua ổ cắm mạng và xử lý dữ liệu định tuyến theo dòng dễ dàng và hiệu quả hơn.

1

Bạn có thể triển khai chức năng tương tự như chức năng của tee với boost::iostreams.

+0

Bạn có ví dụ về C không? Bởi vì đó là đúng C++;) – Skurmedel

+0

xin lỗi có lẽ không phải là – stefanB

2

Không chắc chắn nếu đó là những gì bạn muốn, nhưng 'tee' trong unix làm một cái gì đó tương tự.

+0

Vì vậy, "C + +" guy được modded lên, nhưng bạn nhận được modded xuống cho thấy "xây dựng trên công việc của người khác". Điều đó không đúng ... – Roboprog

4

Điều đầu tiên tôi nghĩ đến cũng là "tee". Vì vậy, chúng ta hãy kết hợp C và vỏ với popen:

FILE * multi_out; 

multi_out = popen("tee file1.out > file2.out", "w"); 
/* error checks, actual work here */ 
pclose(multi_out); 
/* error checks here */ 

Như một bigot Unix, tôi đã giả sử bạn không cố gắng này trên Windows.

+0

Ah, bạn đã nói "Linux". Good boy :-) – Roboprog

+0

Bằng cách này, chúng tôi cũng có thể viết nhiều hơn hai tệp. Chỉ cần vấn đề sử dụng khéo léo của tee. ref. http://www.linuxandlife.com/2013/05/how-to-use-tee-command.html – JagsVG

6

Sử dụng funopen hoặc fwopen và cung cấp chức năng viết của riêng bạn viết cho nhiều FILE* s.

Ví dụ:

FILE *files[2] = ...; 

FILE *f = fwopen((void *)files, my_writefn); 

// ... use f as you like ... 

int my_writefn(void *cookie, const char *data, int n) { 
    FILE **files = (FILE **)cookie; 
    fwrite(data, n, 1, files[0]); 
    return fwrite(data, n, 1, files[1]); 
} 

(Lỗi xử lý bỏ qua.)

Lưu ý rằng funopenfwopen là BSD và không có trong tiêu chuẩn Linux. Tôi không biết nếu có tương đương với Linux.

+0

Rõ ràng là không. Chúng không nằm trong các trang của người đàn ông (ít nhất là trên hệ thống của tôi). – jackhab

+0

funopen là trên BSD và Mac OS X. Trên Linux sử dụng fopencookie. – mark4o

+0

@ mark4o: Cảm ơn bạn đã thông tin. @ Jack: Có vẻ như việc thực hiện bằng cách sử dụng fopencookie() sẽ khá giống nhau. Không cập nhật câu trả lời của tôi ở đây nhưng bạn nên có một số gợi ý để đi tiếp với. – laalto

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