2011-06-09 37 views
10

Tôi muốn tạo thư mục tạm thời duy nhất trong Windows từ một số mã C (không phải C++ hoặc C#). Tôi muốn làm điều này để tôi có thể đặt một số tệp tạm thời trong thư mục và sau đó xóa chúng một cách dễ dàng khi tôi hoàn tất (bằng cách xóa thư mục đệ quy).Tạo thư mục tạm thời duy nhất từ ​​C tinh khiết trong cửa sổ

Tôi về cơ bản đang tìm kiếm một hàm tương đương với chức năng linux mkdtemp . Có câu trả lời C# here và câu trả lời trên this question đề xuất sử dụng Boost. Nhưng vì tôi đang sử dụng C, các giải pháp đó không hoạt động cho tôi.

Điều tốt nhất tôi đã có thể đưa ra cho đến nay là sử dụng GetTempFileName tiếp theo CreateDirectory, nhưng vấn đề ở đó là nếu tôi hỏi GetTempFileName để tạo ra một tên file duy nhất, điều này cũng tạo tệp (mà tôi không muốn, vì tôi muốn tạo thư mục thay thế).

Relatedly, có GetTempPath, mà trả về vị trí của thư mục tạm của người dùng từ môi trường biến - nhưng kể từ khi tôi muốn tạo thư mục của riêng tôi mà tôi có thể an toàn xóa sau, tôi vẫn cần phải tạo ra một thư mục bên trong bất kỳ con đường nào nó sẽ trở lại.

Có vẻ như nếu tôi muốn tạo một thư mục duy nhất, tôi sẽ phải tạo tạo tệp tạm thời, lấy tên, xóa tệp và sau đó tạo thư mục có cùng tên - nghe có vẻ rất lộn xộn . Bất kỳ ý tưởng nào khác?

+3

Ý tưởng trong đoạn cuối cùng của bạn sẽ không hoạt động - nó sẽ tùy thuộc vào điều kiện chủng tộc. –

Trả lời

8

Bạn có thể sử dụng những gì GetTempPath trả về nối với Hướng dẫn để đảm bảo tính duy nhất của thư mục. Bạn có thể tạo Hướng dẫn sử dụng UuidCreate hoặc CoCreateGuid Function.

Để xóa đệ quy thư mục, có một ví dụ ở đây trong C: How to remove directory recursively? thuần túy dựa trên FindFirstFile, FindNextFile, DeleteFile và RemoveDirectory.

Ngoài ra còn có SHFileOperation nhưng nặng hơn và dựa trên các chức năng của Windows Shell và Shell DLL không phải lúc nào cũng muốn, đặc biệt nếu bạn đang viết mã máy chủ.

+0

Tôi đã nghĩ đến việc sử dụng GUID hoặc UUID, nhưng tôi không thể thấy cách chuyển đổi thành chuỗi. Tiếp tục đào tôi mua ['StringFromGUID2'] (http://msdn.microsoft.com/en-us/library/ms683893 (v = VS.85) .aspx), mà có thể làm các trick, miễn là nó thắng không tạo ra các ký tự không thể đi vào tên tập tin? Có vẻ như nó sẽ chỉ tạo ra các chuỗi hex, điều này sẽ ổn thôi. –

+0

@Timothy - các định dạng chuẩn chuẩn là tốt cho tên tệp, nhưng dù sao, vì bạn không cần các định dạng guid này, bạn không cần StringFromGUIS2 một cách rõ ràng, vì bạn cũng có thể tạo tên tệp "thủ công" bằng cách ghép nối 16 byte được viết bằng định dạng thập lục phân. –

3

Sử dụng GetTempPath sau đó CreateDirectory với tên ngẫu nhiên bên dưới, tùy chọn thử lại nếu CreateDirectory không thành công do đã tồn tại. Nhưng nếu thế hệ tên của bạn đủ tốt, khả năng xảy ra va chạm với tên hiện tại nhỏ hơn nhiều so với khả năng người da đen đoán mật khẩu của bạn hoặc thậm chí là khóa riêng của bạn, vì vậy bạn cũng có thể bỏ qua nó.

+1

Đây thực chất là những gì 'mkdtemp' làm (bao gồm cả thử lại, tất nhiên). – andrewdski

2

Sử dụng _tempnamtmpnam_s để tạo tên tệp chưa tồn tại, sau đó sử dụng CreateDirectory để tạo thư mục. Về mặt kỹ thuật, điều kiện chủng tộc nếu bạn làm điều này, trong đó một quy trình khác có khả năng tạo ra một tệp hoặc thư mục với tên đó trong thời gian giữa khi bạn tạo tên tệp và khi bạn tạo thư mục, nhưng tỷ lệ cược đó là khá khó xảy ra. Để bảo vệ chống lại điều đó, bạn có thể lặp lại cho đến khi bạn thành công.

Để loại bỏ đệ quy một cây thư mục, bạn có thể sử dụng SHFileOperation. Ngoài ra, bạn có thể tự thực hiện truyền tải thư mục với FindFirstFile/FindNextFile, DeleteFileRemoveDirectory.

Nếu bạn muốn tự động xóa thư mục khi thoát, hãy đăng ký một hàm bằng cách sử dụng atexit. Điều này sẽ chỉ hoạt động cho việc chấm dứt chương trình bình thường (tức là thông qua chức năng exit hoặc thông qua trở về từ main/WinMain). Điều này sẽ không hoạt động cho việc chấm dứt chương trình bất thường (ví dụ: thông qua abort, vi phạm quyền truy cập, người khác gọi số TerminateProcess, v.v.).

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