基本上,我有一个程序给出一个4兆的压缩文件,它必须将此文件解码为未压缩的~100兆,然后将其压缩回~4兆的文件。我需要将这个中间100兆字节文件存储在驱动器的某个位置(不要将其保留在内存中)。
程序是用C语言编写的,将在MS Windows 7上执行。在解压缩时,没有保证文件夹(具有写访问权限)给予程序(源文件的文件夹可能是只读的,文件夹是目标文件可能尚未指定。)
事实证明这不是一件容易的事:
1)我已经读过一个C函数,它创建一个临时文件,当关闭或程序终止时它会消失。但是,根据我的理解,它试图在根目录中的磁盘C上创建文件,所以如果用户没有权限(普通用户不这样做),这显然会失败
2)我有一个想法,使用环境/系统变量TEMP并在那里创建一个文件,但看着一个随机的Win7 PC没有调整,我看到这个变量指向c:/ windows / temp,和该文件夹拥有“用户”的特定权利 - 也就是说,他们有权读取,执行,创建和写入文件,但不能删除它们,检查它们的属性等。这意味着,我认为,如果程序是用用户权限运行的,它将能够创建一个文件但不能删除它,因此“删除”它的唯一方法是打开文件进行写入然后关闭它,使其成为0长度文件。这也是不希望的,我不知道如何从C
查询系统变量3)所以,基本上,我现在唯一的想法是创建一个打开文件的函数:
和删除功能:
有更好的想法吗?
感谢任何帮助,谢谢!
PS:程序不能使用任何外部库,如MFC等,只能内置标准C函数
答案 0 :(得分:6)
检索为临时文件指定的目录的路径。
为临时文件创建名称。如果是唯一的文件名 生成后,将创建一个空文件并释放其句柄; 否则,只生成一个文件名。
这两个方法为您提供了获取临时文件的位置和名称的简便方法。
UPD:MSDN上的代码示例:Creating and Using a Temporary File。
答案 1 :(得分:0)
#include <windows.h>
#include <iostream>
#include <chrono>
#include <string>
#include <cstdio>
#include <chrono>
using namespace std;
int FileExists(string& filepath)
{
DWORD dwAttrib = GetFileAttributes(filepath.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
int GetTemporaryFilePath(
string filePrefix,
string fileExt,
string& TmpFilePath /*return*/)
{
if (fileExt[0] == '.')
fileExt.erase(0,1);
char TempPath[MAX_PATH] = { 0 };
if (!GetTempPath(MAX_PATH, TempPath))
return -1;
uint16_t tickint = 0;
while(1) {
const int nowlen = 17; char nowstr[nowlen];
const int ticklen = 5; char tickstr[ticklen];
// Milliseconds since 1970
auto ms = chrono::duration_cast<chrono::milliseconds>(
chrono::system_clock::now().time_since_epoch()
);
__int64 nowint = ms.count();
snprintf(nowstr, nowlen, "%016" "I64" "x", nowint);
snprintf(tickstr, ticklen, "%04x", tickint);
TmpFilePath = string(TempPath)
+ filePrefix
+ "." + string(nowstr)
+ "." + string(tickstr)
+ "." + fileExt;
if (!FileExists(TmpFilePath)) {
//Touch File
FILE* w = fopen(TmpFilePath.c_str(), "w");
fclose(w);
break;
}
tickint++;
}
return 0;
}
int main()
{
string TmpFilePath;
GetTemporaryFilePath("MyFile", ".txt", TmpFilePath);
cout << "TmpFilePath: " << TmpFilePath << endl;
return 0;
}