简体   繁体   English

在C,MS Windows系统中创建临时文件

[英]Create temporary file in C, MS Windows system

Basically, i have a program that is given a 4 meg compressed file, it has to decode this file into uncompressed ~ 100 meg, then compress it back into ~4 meg file. 基本上,我有一个程序给出一个4兆的压缩文件,它必须将此文件解码为未压缩的~100兆,然后将其压缩回~4兆的文件。 I need to store this intermediate 100 meg file somewhere on the drive (dont want to keep it in memory). 我需要将这个中间100兆字节文件存储在驱动器上的某个位置(不要将其保存在内存中)。

Program is written in C and will be executed on MS Windows 7. At the moment of uncompressing, no guaranteed folder (with write access) is given to the program (folder with source file might be read only and folder with target file might be not yet specified). 程序是用C语言编写的,将在MS Windows 7上执行。在解压缩时,没有保证文件夹(具有写访问权限)给予程序(源文件的文件夹可能是只读的,带有目标文件的文件夹可能不是但指定)。

This has proven to be not an easy task: 事实证明这不是一件容易的事:

1) I have read about a C function that creates a temp file that will disappear when closed or program is terminated. 1)我已经读过一个C函数,它创建一个临时文件,当关闭或程序终止时它会消失。 However, from what i understand it tries to make the file on disk C, in root directory, so this will obviously fail if user has no rights for that (which normal user doesnt) 但是,根据我的理解,它试图在根目录中的磁盘C上创建文件,所以如果用户没有权限(普通用户不这样做),这显然会失败

2) I had an idea to use environmental/system variable TEMP and create a file there, BUT looking on a random Win7 PC which wasnt tweaked, i see that this variable points to c:/windows/temp, and that folder has specific rights for "users" - that is, they have rights to read, execute, create and write files, but not to delete them, check their attributes, etc. This means, i assume, that if program is ran with user privilleges, it will be able to make a file but not able to delete it, so the only way to "delete" it would be to open the file for writing and then close it, making it a 0 length file. 2)我有一个想法,使用环境/系统变量TEMP并在那里创建一个文件,但看着一个随机的Win7 PC没有调整,我看到这个变量指向c:/ windows / temp,该文件夹具有特定的权利对于“用户” - 也就是说,他们有权读取,执行,创建和写入文件,但不能删除它们,检查它们的属性等。这意味着,我认为,如果程序是使用用户权限运行的,它将会能够创建一个文件但不能删除它,所以“删除”它的唯一方法是打开文件进行写入然后关闭它,使其成为一个0长度的文件。 This is also not desired, and i dont know how to query for system variables from C 这也是不希望的,我不知道如何从C查询系统变量

3) So, basically, only idea i have right now is to make a function to open file that: 3)所以,基本上,我现在唯一的想法是创建一个函数来打开以下文件:

  • tries to create a temp file in the output dir, if possible 尝试在输出目录中创建临时文件(如果可能)
  • if failed, tries to create a temp file in input dir 如果失败,尝试在输入目录中创建临时文件
  • if failed, tries to create a temp file in TEMP dir from system variable 如果失败,尝试从系统变量创建TEMP目录中的临时文件
  • if failed, tries to create a temp file in TMP dir from system variable 如果失败,尝试从系统变量在TMP目录中创建临时文件

and a delete function that: 和删除功能:

  • tries to remove() the file (by its name that is stored somewhere) 尝试删除()文件(通过其存储在某处的名称)
  • if failed, it tries to open the file for write, and close it, so it becomes a 0 byte file 如果失败,它会尝试打开文件进行写入,然后将其关闭,这样它就变成了一个0字节的文件

Are there better ideas? 有更好的想法吗?

Any help is appreciated, thanks! 任何帮助表示赞赏,谢谢!

PS: Program must not use any external libraries like MFC or something, only built-in standart C functions PS:程序不能使用任何外部库,如MFC等,只能使用内置的标准C函数

GetTempPath

Retrieves the path of the directory designated for temporary files. 检索为临时文件指定的目录的路径。

GetTempFileName

Creates a name for a temporary file. 为临时文件创建名称。 If a unique file name is generated, an empty file is created and the handle to it is released; 如果生成了唯一的文件名,则会创建一个空文件并释放其句柄; otherwise, only a file name is generated. 否则,仅生成文件名。

These two provide you easy way to obtain a location and name for a temporary file. 这两个为您提供了获取临时文件的位置和名称的简便方法。

UPD: Code sample on MSDN: Creating and Using a Temporary File . UPD:MSDN上的代码示例: 创建和使用临时文件

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM