2009-10-28 15 views
11

Khi tôi lưu tệp trên USB trong ứng dụng delphi của mình, làm cách nào để đảm bảo tệp thực sự (vĩnh viễn) được lưu trên USB khi "Safely Remove Hardware" không được thực hiện (đặc biệt là bị lãng quên khi sử dụng)?
Nói cho khách hàng của chúng tôi sử dụng tính năng cửa sổ "Safely Remove Hardware" không hoạt động.
Có lệnh API cửa sổ để xóa bộ đệm, sao cho tất cả dữ liệu được ghi vào ổ USB vĩnh viễn?Làm cách nào để đảm bảo rằng tệp được lưu vĩnh viễn trên USB, khi người dùng không sử dụng "Safely Remove Hardware"?

+7

Cho bất kỳ ai đã bỏ phiếu để đóng là "Không liên quan đến lập trình", vui lòng đọc lại câu hỏi. –

+0

Tương tự ở đây. Câu hỏi đặt ra là rất nhiều chương trình liên quan. –

+1

Tôi chưa bao giờ bị mất dữ liệu mà tôi có thể thuộc tính để xóa thiết bị lưu trữ USB mà không thực hiện "gỡ bỏ phần cứng an toàn". Tôi đảm bảo rằng các toán hạng sao chép tệp hoàn tất (hộp thoại 'sao chép tệp' biến mất). Tôi có may mắn không? – Les

Trả lời

3

Dưới đây là một chức năng tôi sử dụng để tuôn ra dữ liệu vào một ổ đĩa USB trước khi tháo nó lập trình. Chức năng nhân bản này từ Mark Russinovich's "Sync" utility. Tôi đã không có vấn đề với mã này và nó đã được chạy trên rất nhiều hệ thống trong một vài năm.

Phần có liên quan nhất của mã này là gọi tới FlushFileBuffers.

function FlushToDisk(sDriveLetter: string): boolean; 
var 
    hDrive: THandle; 
    S:  string; 
    OSFlushed: boolean; 
    bResult: boolean; 
begin 
    bResult := False; 
    S := '\\.\' + sDriveLetter + ':'; 

    //NOTE: this may only work for the SYSTEM user 
    hDrive := CreateFile(PAnsiChar(S), GENERIC_READ or 
    GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, 
    OPEN_EXISTING, 0, 0); 
    OSFlushed := FlushFileBuffers(hDrive); 

    CloseHandle(hDrive); 

    if OSFlushed then 
    begin 
    bResult := True; 
    end; 

    Result := bResult; 
end; 
+2

Đó là để xóa tất cả các tệp đang mở trên ổ đĩa. Nếu Max chỉ quan tâm đến các tệp mà chương trình của anh ấy đang viết và không phải với bất kỳ tệp nào khác mà người dùng có thể đang ghi vào ổ đĩa thông qua các phương tiện khác, thì anh ấy có thể chỉ cần xử lý các tệp của mình thay vì xóa toàn bộ âm lượng và do đó anh ta sẽ không cần quyền quản trị. –

+0

Nó gần như không thể đảm bảo sẽ không có một số tham nhũng. Đĩa flash có thể được rút ra bất cứ lúc nào. Tôi nghĩ rằng câu trả lời của MSalters chính xác hơn. Tôi đồng ý với Rob, đó là đĩa rộng. – Matt

+0

Tại sao mã này sử dụng 3 vars (OSFlushed, bResult và Result) khi chỉ một người có vẻ thực hiện công việc? – EMBarbosa

2

bất cứ điều gì xảy ra, bạn có thể tự rút phích cắm thiết bị, ý tôi là lập trình. sau đó bạn sẽ hoàn toàn chắc chắn rằng họ đã gỡ bỏ thiết bị đúng cách.

hãy xem câu trả lời cho câu hỏi này: safe-remove-usb-drive-using-win32-api. đặc biệt là this link to a msdn kb article được đưa ra trong câu trả lời.

+1

Nhưng nếu người dùng không muốn tháo ổ USB thì sao? – simon

+0

người dùng đã xóa ổ USB, tôi không nghĩ rằng anh ấy cần nó nữa. nghiêm túc hơn, nếu anh ta chờ đợi lâu hơn để sử dụng ổ đĩa, tập tin sẽ kết thúc bằng văn bản vào đĩa (tệp không được lưu giữ trong bộ nhớ cache mãi mãi). (tôi đang xử lý hàng ngày với loại khách hàng này, đơn giản hơn là dành cho họ, nó càng tốt cho tất cả mọi người. hãy nói với họ rằng họ không thể sử dụng ổ đĩa, điều đó đơn giản; hãy nói với họ rằng họ phải đi đến "gỡ bỏ phần cứng một cách an toàn", Tôi có thể đặt cược OP của chúng tôi đã có một số mã để tự động phát hiện ổ đĩa USB chèn và sao chép các tập tin cần thiết cho một đường dẫn định trước) –

+1

Adrien, chúng tôi chỉ biết người dùng đang loại bỏ ổ đĩa * đôi khi *. Chúng tôi không biết rằng người dùng * luôn * xóa ổ đĩa sau khi lưu. Chúng tôi cũng không biết liệu ổ đĩa có đang được sử dụng cho những thứ khác ngoài chương trình này hay không. –

11

Khi bạn mở tệp, chỉ định "viết qua" (FILE_FLAG_WRITE_THROUGH cờ tới CreateFile()). Điều này sẽ buộc hệ điều hành phải ghi trực tiếp tệp. Nó có thể vẫn còn trong bộ nhớ cache của hệ điều hành để tăng tốc độ đọc tiếp theo, nhưng đó không phải là một vấn đề cho bạn.

Nếu bạn muốn tuôn bộ đệm tập tin, có tất nhiên luôn FlushFileBuffers()

+0

Khi tôi sử dụng FlushFileBuffers(), tôi có thể chắc chắn rằng tệp được lưu trữ trên ổ đĩa USB không? Vì vậy, nó không biến mất, sau khi rút phích cắm "không kiểm soát được"? –

+1

@max: Có, miễn là có đủ thời gian giữa các cuộc gọi đến FlushFileBuffers() và việc loại bỏ các ghi vật lý xảy ra. IOW, nếu bạn thử và ghi một tệp 2GB vào đĩa USB, hãy gọi FlushFileBuffers(), và sau đó + ngay lập tức + xóa ổ đĩa, nó vẫn có thể không được viết hoàn toàn - không đủ thời gian để hoàn thành thao tác ghi thực tế. Bạn cần phải hướng dẫn người dùng về cách xóa ổ đĩa một cách an toàn hoặc ít nhất hãy đợi cho đến khi ứng dụng của bạn cho biết họ có thể xóa nó; ứng dụng của bạn có thể tìm ra thời gian cần chờ đợi trước khi cho chúng OK. –

+3

Ken, bạn làm cho nó âm thanh như FlushFileBuffers sẽ trở lại trước khi nó đã thực sự hoàn thành xả bộ đệm tệp. Đúng không? Nếu có, thì * cách * nên chương trình tìm ra thời gian cần chờ đợi bao lâu? –

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