2009-04-26 25 views
6

Tôi đang cố gắng mở tệp văn bản để đọc trong ứng dụng Delphi 7, nhưng đang gặp lỗi I/O 32 (chia sẻ vi phạm) vì ứng dụng khác đã mở tệp. Tôi đã cố gắng thiết lập FileMode để "fmOpenRead hoặc fmShareDenyNone" nhưng bây giờ nhận ra điều này không áp dụng cho các tập tin văn bản anyway.Delphi - Chia sẻ tệp văn bản mở vi phạm

Có cách nào để đọc tệp văn bản được mở bởi ứng dụng khác không?

var 
    f: TextFile; 
begin 
    FileMode := fmOpenRead or fmShareDenyNone; // FileMode IS NOT APPLICABLE TO TEXT FILES!! 
    AssignFile(f, FileName); 
    Reset(f); 
+0

Tại sao bạn lại quan tâm đến tệp văn bản? Tại sao không sử dụng các lớp luồng cho phép truy cập và chia sẻ tệp đúng cách? – mghie

+0

vì tôi muốn đọc một dòng tại một thời điểm và TFileStream không có phương thức cho điều đó. Tôi cho rằng tôi có thể đọc một bộ đệm đầy đủ và chia thành CR/LF. – Simes

+1

Bạn có thể sử dụng 'TStreamReader' để đọc các dòng từ' TFileStream'. Nó có một phương thức 'ReadLine()' và thực hiện việc đệm trong nội bộ cho bạn. –

Trả lời

1

Điều này sẽ khắc phục sự cố của bạn ngay lập tức. Tải tệp bằng TStringList. Chỉ cần gọi:

... 
var sl: TStringList; 
begin 
    sl := TStringList.create(); 
    try 
    sl.loadFromFile(Filename); 
    ...do your stuff here... 
    finally 
    freeAndNil(sl); 
    end; 
end; 

Tôi thấy rằng việc xử lý các tệp văn bản, tốt nhất là sử dụng TStringList. Nếu không tôi sẽ đi cho TFileStream và ở đó bạn có thể chỉ định chế độ mở của bạn.

+0

không hữu ích? Simes, bạn đã thử cái này chưa? –

+0

LoadFromFile() sử dụng (ít nhất là trong Delphi 5 và 2007 nó)) "fmOpenRead hoặc fmShareDenyWrite" cho chế độ. Điều này chắc chắn không phải là những gì OP mong muốn. – mghie

+0

??? Đây chính là điều mà Simes muốn. Anh ta chỉ muốn ĐỌC tệp mà không quan tâm đến các quy trình khác bằng cách sử dụng nó. Đó chính là câu hỏi của anh. –

3

Nó phụ thuộc vào cách mà quá trình khác đã mở tệp ... Nếu nó mở tệp độc quyền, bạn sẽ không thành công chút nào.

Và TextFile là chiếc mũ cũ, tôi nghĩ nó sẽ mở ở chế độ độc quyền để tương thích với kiểu DOS cũ. Bạn nên sử dụng TFileStream hoặc tương tự.

TStringList cũng có thể hoạt động lại, tùy thuộc vào quá trình khác đang thực hiện. Nhưng nếu tệp đang được viết (như tệp .log) thì fmShareDenyWrite sẽ không hoạt động.

+0

Tôi không biết làm thế nào quá trình khác đang mở tập tin, nhưng Notepad có thể mở nó thành công trong khi nó đang được ghi vào. – Simes

+0

Có vẻ như bạn đang gặp may. Chỉ cần mương TextFile. –

+0

@Simes, tôi phác thảo quy trình cho bạn biết chính xác cách các tệp đang được mở, tại đây: http://stackoverflow.com/questions/737053/log-file-monitor/739328#739328 –

1

Nếu tôi nhớ chính xác, cũng có một biến Textfilemode chỉ áp dụng cho các tệp văn bản.

+0

Điều đó sẽ hoàn hảo, nhưng nó không biên dịch và không thể tìm thấy nó trong trợ giúp. – Simes

1

Có lẽ như thế này:

vFileList := TStringList.Create; 
    try 
    vFileStream := TFileStream.Create('myfile.txt', fmOpenRead or fmShareDenyNone); 
    try 
     vFileList.LoadFromStream(vFileStream); 
    finally 
     vFileStream.Free; 
    end; 
    // Use vFileList 
    finally 
    vFileList.Free; 
    end; 
12

Sử dụng phương pháp LoadFromStream của TStringList, chứ không phải là LoadFromFile. Bạn có thể kiểm soát khóa theo cách đó:

var 
    slFile: TStrings; 
    stream: TStream; 
begin 
    slFile := TStringList.Create; 
    try 
     stream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone); 
     try 
     slFile.LoadFromStream(stream); 
     finally 
     stream.Free; 
     end; 

     //Use the stringlist 
    finally 
     slFile.Free; 
    end; 
end; 

Ví dụ đó đang sử dụng luồng để tải vào TStringList. Nếu bạn chỉ muốn đọc các phần, bạn có thể làm điều đó. Chỉ cần đọc từ luồng.

+0

Tác phẩm này và giải quyết vấn đề. Chỉ lo ngại về việc sử dụng bộ nhớ: toàn bộ tệp được tải vào bộ nhớ. Đây có thể là một vấn đề. – Ghigo

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