2011-08-25 27 views
6

Ứng dụng của tôi (chương trình C) mở hai bộ xử lý tập tin vào cùng một tập tin (một ghi và một ở chế độ đọc). Hai chủ đề riêng biệt trong ứng dụng đọc và ghi vào tệp. Điều này hoạt động tốt. Vì ứng dụng của tôi chạy trên thiết bị nhúng với kích thước đĩa ram giới hạn, tôi muốn viết FileHandle để bọc vào đầu tệp khi đạt kích thước tối đa và đọc FileHandle để làm theo như bộ đệm tròn. Tôi hiểu câu trả lời cho this question rằng điều này sẽ hoạt động. Tuy nhiên ngay sau khi tôi làm fseek ghi số FileHandle vào đầu tệp, fread trả về lỗi. Liệu số EOF có được đặt lại khi thực hiện fseek để bắt đầu tệp không? Nếu vậy, chức năng nào nên được sử dụng để gây ra vị trí ghi tập tin để có được thiết lập để 0 mà không gây ra EOF để được thiết lập lại.Làm thế nào để thực hiện một bộ đệm tròn bằng cách sử dụng một tập tin?

EDIT/UPDATE: tôi đã cố gắng vài điều:


  1. Dựa trên @neodelphi tôi đã sử dụng ống làm việc này. Tuy nhiên, usecase của tôi yêu cầu tôi ghi vào một tập tin. Tôi nhận được nhiều kênh của luồng giám sát video trực tiếp cần được lưu trữ vào đĩa cứng và cũng đọc lại được giải mã và hiển thị trên màn hình.

  2. Nhờ các đề xuất @Clement khi thực hiện ftell, tôi đã sửa một số lỗi trong mã và công việc của mình cho người đọc, dữ liệu đọc dường như là dữ liệu cũ vì ghi vẫn được đệm nhưng người đọc đọc nội dung cũ từ khó đĩa. Tôi không thể tránh đệm do các cân nhắc về hiệu suất (tôi nhận được 32Mbps dữ liệu trực tiếp cần được ghi vào đĩa cứng). Tôi đã thử những thứ như flushing viết chỉ trong khoảng thời gian từ khi viết kết thúc tốt đẹp đến khi đọc kết thúc tốt đẹp và cắt ngắn các tập tin (ftruncate) sau khi đọc kết thúc tốt đẹp nhưng điều này doesnt giải quyết vấn đề dữ liệu cũ.

  3. Tôi cố gắng để sử dụng hai tập tin trong thời trang ping-pong để xem nếu điều này giải quyết vấn đề này nhưng muốn biết nếu có một giải pháp tốt hơn

+0

Bạn có đang khóa khi đang đọc tệp không? –

+1

Nếu bạn đang phát triển trên một hệ thống giống như Linux, bạn đã thử các tệp đường ống chưa? Các loại tệp này chỉ lưu trữ những gì đã được viết nhưng không đọc, do đó việc triển khai bộ đệm tròn có thể không cần thiết. – neodelphi

+0

@Clement. Tôi không có ổ khóa. Tôi sử dụng std C lib fread và fwrite gọi – Badri

Trả lời

1

Bạn nên có một cái gì đó như thế:

// Write 
if(ftell(WriteHandle)>BUFFER_MAX) rewind (WriteHandle); 
fwrite(WriteHandle,/* ... */); 

// Read (assuming binary) 
readSize = fread (buffer,1,READ_CHUNK_SIZE,ReadHandle); 
if(readSize!=READ_CHUNK_SIZE){ 
    rewind (ReadHandle); 
    if(fread (buffer+readSize,1,READ_CHUNK_SIZE-readSize,ReadHandle)!=READ_CHUNK_SIZE-readSize) 
     ;// ERROR ! 
} 

Không được thử nghiệm, nhưng nó đưa ra một ý tưởng. Việc viết cũng nên xử lý các trường hợp BUFFER_MAX không phải là modulo WRITE_CHUNK_SIZE.

Ngoài ra, bạn chỉ có thể đọc nếu bạn chắc chắn rằng dữ liệu đã được ghi. Nhưng tôi đoán bạn đã làm điều đó.

+0

Dưới đây là mã của tôi. Tương tự như những gì bạn có ngoại trừ tôi sử dụng fseek thay vì rewind.' fpos = ftell (fp); if ((fpos + bytesToWrite)> = maxFileSize) {fseek (fp, 0, SEEK_SET);} ' – Badri

+0

@Bardi fread don ' chỉ trả về lỗi, nó trả về một số. Số nào? 'Feof()' trả về là gì? Ngoài ra, 'feof()' được đặt lại trên fseek, rewind và clearerr (http://www.cplusplus.com/reference/clibrary/cstdio/clearerr/). –

+0

Khi viết bìa, tôi đặt vị trí quấn trong biến được chia sẻ (với bảo vệ mutex). Khi đọc vị trí đạt đến vị trí bọc này, tôi làm tua lại xử lý tập tin đọc ngay cả trước khi làm fread. Vì vậy, tôi sẽ mong đợi không có lỗi xảy ra. Tôi nhận được lỗi fread ngay sau khi viết kết thúc tốt đẹp xung quanh mặc dù vị trí đọc vẫn chưa đạt đến điểm bọc. Đọc sẽ luôn có kích thước giống như viết kích thước chunk trong ứng dụng của tôi – Badri

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