看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《leslieha (懂的付出才會幸福)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : DBD 6.0 : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : 問題(Question): : 把resource內的資料 : 直接開啟 : 而不用先存成檔案 : 程式碼(Code):(請善用置底文網頁, 記得排版) : TResourceStream* res = new TResourceStream((int)HInstance, : MY_MSG_FORMAT_289, : "PDF"); : if(res == 0) : { : ShowMessage("TResourceStream fail"); : return; : } : else : { : res->SaveToFile("test.pdf"); : ShellExecute(NULL, "Open", "test.pdf" ,NULL,NULL,SW_MAXIMIZE); : } : 補充說明(Supplement): : res->SaveToFile("test.pdf"); : 將resource內的資料存程test.pdf : ShellExecute(NULL, "Open", "test.pdf" ,NULL,NULL,SW_MAXIMIZE); : 將test.pdf開啟 : 目前程式如預期運作 : 但是會增加一個test.pdf中繼檔 : 考量到以後會有很多資料包到resource內 : 若以後皆用此方法,會產生很多個 pdf : 若執行檔是被燒到CD-ROM上 : 此方法應該行不通 : 請問 : 是否有辦法連test.pdf中繼檔都不用產生 : 即可用pdf reader開起pdf檔? http://www.eterlogic.com/help/vdsdk/CppPage2_5.html http://www.eterlogic.com/help/vdsdk/index.html Virtual Drive SDK (商業軟體),可以動態建立、刪除磁碟槽,比如 Z: 之後的讀寫可以轉到指定的記憶體位址。 沒試過,不知道還能不能進一步產生 Z:\test.pdf 供 pdf reader 讀取。 如果這個不能就找其他商業的 Ram Disk 相關軟體吧, 在 Windows 應該是沒有內建的解決方案。 Linux 好像有個 tmpfs 我也沒試過,不知道具體效果,反正你也不用 Linux。 Wikipedia 是寫說 Windows 可以用 FILE_ATTRIBUTE_TEMPORARY + CreateFile() 代替 tmpfs,這我測過。 新增一個 tmp.txt 再把硬碟上的 menu.lst 檔案內容寫入 進去,先不關檔案,用其他程式開啟 tmp.txt,結果無法開啟檔案,程式碼如下: #include <windows.h> #include <stdio.h> #include <conio.h> int main() { HANDLE hFile = ::CreateFileA("tmp.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); HANDLE hSrcFile = ::CreateFileA("D:\\Desktop\\menu.lst", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); DWORD dwBytesRead, dwBytesWritten, dwPos; BYTE buff[4096]; while (ReadFile(hSrcFile, buff, sizeof(buff), &dwBytesRead, NULL) && dwBytesRead > 0) { dwPos = SetFilePointer(hFile, 0, NULL, FILE_END); WriteFile(hFile, buff, dwBytesRead, &dwBytesWritten, NULL); } CloseHandle(hSrcFile); puts("Wait for another process"); _getch(); CloseHandle(hFile); return 0; } 參考資料: http://msdn.microsoft.com/en-us/library/aa363858.aspx#caching_behavior http://blogs.msdn.com/b/larryosterman/archive/2004/04/19/116084.aspx 把 FILE_FLAG_DELETE_ON_CLOSE 拿掉就能開啟,但開啟後又不知道怎麼確定 是真的從記憶體讀取,中間沒牽涉到硬碟,所以算了。 感覺你只是要避免產生檔案這件事而已,那其實最好的方法是用 Shared Memory, 也就是你的程式在記憶體裡面放 pdf 資料,另外的程式也到這個共享的記憶體去讀取, 但是這方法要程式二主動呼叫 OpenFileMapping 才行,你干涉不了的, 除非兩邊的程式都你在維護才適用。 Creating Named Shared Memory: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551.aspx 一般狀況應該是像 PTT 這種伺服器,可能一萬個人傳資料過來,每份都必須存成 一個檔案 A0~A9999,但檔案每個都不大,又很少會被讀取,也許幾個小時內,只有 幾份 Ax 有被人拿去用,這種情況下,檔案不必急著寫入,可以推遲, 這可能才是前面 FILE_ATTRIBUTE_TEMPORARY 的主要目的吧? 每個作業系統都會有一大份主記憶體用來對硬碟檔案快取,應該是透過 OS 的 cache manager 去處理,反正只要快取記憶體還夠用,就不寫入這些檔案到硬碟去, 晚點再存。另外如果你的 PDF 一開始是從硬碟單獨讀取上來的檔案,那大可有機會 被快取到記憶體,第二個程式開同樣檔案時,也未必要再讀一次硬碟,只是你堅持要 把 PDF 塞到 resource 裡,那 cache manager 來說,大概是很難快取吧。 我想商業上如果卡在大量的硬碟讀寫,要嘛是研究 Windows 的快取機制,看怎樣用內建 的工具跑出最高效率,要嘛就真的是用 RAMDISK,一開始就用主記憶體模擬硬碟,就像 最前面提的 Virtual Drive SDK 那樣。 沒經驗純粹猜測而已,附帶一提的是,之前喵到 Windows Internal 這書對快取機制 有蠻多探討,有需要的人可以找這管道。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 124.8.137.112 ※ 編輯: purpose 來自: 124.8.137.112 (04/28 03:46)
EdisonX:想請教p大,RamDisk技術,是否即是將ram 當 disk使用?那記憶 04/30 09:49
EdisonX:體不夠切的話是否就是allocate fail?細思這行為似乎和 04/30 09:49
EdisonX:MemoryMappedFile 機制相仿? 04/30 09:50
EdisonX:我於文中找到答案了,請略過上述敘述,謝謝分享 ^^ 04/30 10:04