2008-09-24 34 views
15

Câu hỏi của tôi là dựa trên kế thừa rất nhiều mã di sản mà tôi không thể làm rất nhiều về. Về cơ bản, tôi có một thiết bị sẽ tạo ra một khối dữ liệu. Một thư viện sẽ gọi thiết bị để tạo khối dữ liệu đó, vì một lý do nào đó tôi không hiểu hoàn toàn và không thể thay đổi ngay cả khi tôi muốn, ghi khối dữ liệu đó vào đĩa.C# tập tin đọc/ghi tập tinkhông xuất hiện để làm việc

Ghi này không tức thời, nhưng có thể mất đến 90 giây. Trong thời gian đó, người dùng muốn xem một phần dữ liệu đang được tạo ra, vì vậy tôi muốn có một luồng người tiêu dùng đọc dữ liệu mà thư viện khác đang ghi vào đĩa.

Trước khi tôi thậm chí chạm vào mã kế thừa này, tôi muốn bắt chước vấn đề bằng mã tôi hoàn toàn kiểm soát. Tôi đang sử dụng C#, bề ngoài bởi vì nó cung cấp rất nhiều chức năng tôi muốn.

Trong lớp nhà sản xuất, tôi có mã này tạo ra một khối ngẫu nhiên của dữ liệu:

FileStream theFS = new FileStream(this.ScannerRawFileName, 
    FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); 
//note that I need to be able to read this elsewhere... 
BinaryWriter theBinaryWriter = new BinaryWriter(theFS); 
int y, x; 
for (y = 0; y < imheight; y++){ 
    ushort[] theData= new ushort[imwidth]; 
    for(x = 0; x < imwidth;x++){ 
     theData[x] = (ushort)(2*y+4*x); 
    } 
    byte[] theNewArray = new byte[imwidth * 2]; 
    Buffer.BlockCopy(theImage, 0, theNewArray, 0, imwidth * 2); 
    theBinaryWriter.Write(theNewArray); 
    Thread.Sleep(mScanThreadWait); //sleep for 50 milliseconds 
    Progress = (float)(y-1 >= 0 ? y-1 : 0)/(float)imheight; 
} 
theFS.Close(); 

Cho đến nay, như vậy tốt. Mã này hoạt động. Phiên bản hiện tại (sử dụng FileStream và BinaryWriter) có vẻ tương đương (mặc dù chậm hơn, vì bản sao) để sử dụng File.Open với các tùy chọn tương tự và một BinaryFormatter trên ushort [] được ghi vào đĩa.

Nhưng sau đó tôi thêm một sợi tiêu dùng:

FileStream theFS; 
if (!File.Exists(theFileName)) { 
    //do error handling 
    return; 
} 
else { 
    theFS = new FileStream(theFileName, FileMode.Open, 
     FileAccess.Read, FileShare.Read); 
      //very relaxed file opening 
} 
BinaryReader theReader = new BinaryReader(theFS); 

//gotta do this copying in order to handle byte array swaps 
//frustrating, but true. 
byte[] theNewArray = theReader.ReadBytes(
    (int)(imheight * imwidth * inBase.Progress) * 2); 
ushort[] theData = new ushort[((int)(theNewArray.Length/2))]; 
Buffer.BlockCopy(theNewArray, 0, theData, 0, theNewArray.Length); 

Bây giờ, nó có thể là tuyên bố của theNewArray bị hỏng, và sẽ gây ra một số loại tràn đọc. Tuy nhiên, mã này không bao giờ nhận được rằng đến nay, bởi vì nó luôn luôn luôn luôn phá vỡ trên cố gắng để mở FileStream mới với một System.IO.IOException rằng nói rằng một quá trình đã mở tập tin.

Tôi đang đặt FileAccess và FileShare liệt kê trong tài liệu FileStream trên MSDN, nhưng có vẻ như tôi không thể làm những gì tôi muốn làm (ví dụ, viết trong một chủ đề, đọc trong một chủ đề khác). Tôi nhận ra rằng ứng dụng này là một chút không chính thống, nhưng khi tôi nhận được các thiết bị thực tế liên quan, tôi sẽ phải làm điều tương tự, nhưng bằng cách sử dụng MFC.

Trong mọi trường hợp, Tôi quên gì? Là những gì tôi muốn làm có thể, vì nó được chỉ định càng tốt trong tài liệu?

Cảm ơn! mmr

Trả lời

3

Tôi đã không có thời gian để kiểm tra điều này nhưng tôi nghĩ rằng bạn có thể cần phải gọi phương thức Flush của BinaryWriter

FileStream theFS = new FileStream(this.ScannerRawFileName, 
    FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); 
//note that I need to be able to read this elsewhere... 
BinaryWriter theBinaryWriter = new BinaryWriter(theFS); 
int y, x; 
for (y = 0; y < imheight; y++){ 
    ushort[] theData= new ushort[imwidth]; 
    for(x = 0; x < imwidth;x++){ 
     theData[x] = (ushort)(2*y+4*x); 
    } 
    byte[] theNewArray = new byte[imwidth * 2]; 
    Buffer.BlockCopy(theImage, 0, theNewArray, 0, imwidth * 2); 
    theBinaryWriter.Write(theNewArray); 
    Thread.Sleep(mScanThreadWait); //sleep for 50 milliseconds 
    Progress = (float)(y-1 >= 0 ? y-1 : 0)/(float)imheight; 
    theBinaryWriter.Flush(); 
} 
theFS.Close(); 

Xin lỗi tôi đã không có thời gian để kiểm tra điều này. Tôi chạy vào một vấn đề với một tập tin tôi đã tạo ra là tương tự như điều này (mặc dù không chính xác) và một thiếu "Flush" là thủ phạm.

34

Người tiêu dùng của bạn phải chỉ định FileShare.ReadWrite.

Bằng cách cố gắng mở tệp dưới dạng FileShare.Read trong người tiêu dùng, bạn đang nói "Tôi muốn mở tệp và cho phép người khác đọc tệp đó cùng lúc" ... vì có đã là một nhà văn gọi thất bại, bạn phải cho phép viết đồng thời với người đọc.

2

Tôi tin Chuck là đúng, nhưng hãy nhớ rằng lý do duy nhất làm việc này là vì hệ thống tập tin đủ thông minh để tuần tự hóa việc đọc/ghi của bạn; bạn không có khóa trên tài nguyên tập tin - đó không phải là một điều tốt :)

+0

Đủ công bằng-- nhưng hãy nhớ, tôi phải làm điều này với mã cũ mà hầu như chắc chắn không có khóa tập tin nào (và những người đã viết mã đó sẽ nhìn vào bạn như bạn là hạt cho thấy rằng có những thứ như vậy). Vì vậy, nếu nó phá vỡ vì điều đó, tôi tốt nhất bắt chước những giờ nghỉ. – mmr

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