-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTempFile.hpp
115 lines (100 loc) · 3.44 KB
/
TempFile.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// TempFile.hpp --- 一時ファイルを自動化する by katahiromz
#pragma once
#include <strsafe.h> // 文字列を安全に扱う関数(StringCc*)。
#include <cassert> // assertマクロ。
// 一時ファイルを扱うクラス。
class TempFile
{
protected:
DWORD m_old_value;
TCHAR m_tempfile[MAX_PATH]; // ファイル名。
TCHAR m_temppath[MAX_PATH]; // パスファイル名。
TCHAR m_prefix[4]; // プレフィックス。
TCHAR m_dot_ext[8]; // 拡張子(ドットで始まる)。
// ファイル名を多様にするための調味料。
DWORD get_salt()
{
// 現在の時刻データを利用する。
SYSTEMTIME st;
::GetLocalTime(&st);
DWORD dw = m_old_value; // 古い値も利用する。
dw += st.wYear;
dw += st.wMonth;
dw += st.wDay;
dw += st.wHour;
dw += st.wMinute;
dw += st.wSecond;
dw += st.wMilliseconds;
m_old_value = dw; // 値を保存する。
return LOWORD(dw) ^ HIWORD(dw); // 値は符号なし2バイト整数の範囲。
}
public:
// コンストラクタ。
TempFile() : m_old_value(::GetTickCount())
{
m_tempfile[0] = m_temppath[0] = m_prefix[0] = m_dot_ext[0] = 0;
}
// コンストラクタ。
TempFile(LPCTSTR prefix, LPCTSTR dot_ext) : m_old_value(::GetTickCount())
{
init(prefix, dot_ext);
}
// デストラクタ。
~TempFile()
{
// 自動的に削除する。
erase();
}
// 初期化。第一引数はプレフィックス。第二引数は拡張子。
void init(LPCTSTR prefix, LPCTSTR dot_ext)
{
m_tempfile[0] = 0;
::GetTempPath(_countof(m_temppath), m_temppath);
StringCchCopy(m_prefix, _countof(m_prefix), prefix);
StringCchCopy(m_dot_ext, _countof(m_dot_ext), dot_ext);
assert(dot_ext[0] == TEXT('.') || dot_ext[0] == 0);
}
// 一時ファイルを作成し、パスファイル名を返す。
LPCTSTR make()
{
for (UINT i = 0; i < 1000; ++i) // 1000回やってダメならあきらめよう。
{
// 調味料を使ってパスファイル名を作成する。
StringCchPrintf(m_tempfile, _countof(m_tempfile),
TEXT("%s%s-%04lX%s"),
m_temppath, m_prefix, get_salt(), m_dot_ext);
// 新しく作成できたら、それを採用。
HANDLE hFile = ::CreateFile(m_tempfile, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
::CloseHandle(hFile);
return m_tempfile;
}
// 作成できなかったらやり直す。
}
// 作成失敗。
assert(0);
m_tempfile[0] = 0;
return NULL;
}
// パスファイル名を返す。
LPCTSTR get() const
{
assert(m_tempfile[0] != 0); // make first!
if (m_tempfile[0] != 0)
return m_tempfile;
return NULL;
}
// 一時ファイルを削除する。
void erase()
{
if (m_tempfile[0])
::DeleteFile(m_tempfile);
}
// 名前をクリアする。削除されてなければこのクラスは一時ファイルを削除しない。
void clear()
{
m_tempfile[0] = 0;
}
};