7

基本的に、4メガの圧縮ファイルが与えられたプログラムがあります。このファイルを非圧縮の〜100メガにデコードしてから、〜4メガのファイルに圧縮する必要があります。この 100 MB の中間ファイルをドライブのどこかに保存する必要があります (メモリに保存したくありません)。

プログラムは C で記述されており、MS Windows 7 で実行されます。解凍の時点で、保証されたフォルダー (書き込みアクセス権付き) がプログラムに与えられません (ソース ファイルを含むフォルダーは読み取り専用で、ターゲット ファイルを含むフォルダーは読み取り専用ではない可能性があります)。まだ指定されていません)。

これは簡単な作業ではないことが証明されています。

1) 閉じるかプログラムを終了すると消える一時ファイルを作成する C 関数について読みました。ただし、私が理解していることから、ディスクCのルートディレクトリにファイルを作成しようとするため、ユーザーにその権限がない場合(通常のユーザーにはありません)、これは明らかに失敗します

2)環境/システム変数TEMPを使用してそこにファイルを作成するという考えがありましたが、微調整されていないランダムなWin7 PCを見ると、この変数がc:/ windows / tempを指しており、そのフォルダーには特定の権利があることがわかります「ユーザー」の場合-つまり、ファイルの読み取り、実行、作成、書き込みの権限がありますが、ファイルの削除、属性の確認などはできません。これは、プログラムがユーザー権限で実行されている場合、ファイルを作成することはできますが、削除することはできません。そのため、「削除」する唯一の方法は、ファイルを書き込み用に開いてから閉じて、長さ 0 のファイルにすることです。これも望ましくありません。C からシステム変数を照会する方法がわかりません。

3)したがって、基本的に、私が今持っている唯一のアイデアは、ファイルを開く関数を作成することです:

  • 可能であれば、出力ディレクトリに一時ファイルを作成しようとします
  • 失敗した場合、入力ディレクトリに一時ファイルの作成を試みます
  • 失敗した場合は、システム変数から TEMP ディレクトリに一時ファイルの作成を試みます
  • 失敗した場合は、システム変数から TMP ディレクトリに一時ファイルを作成しようとします

および削除機能:

  • ファイルの remove() を試みます (どこかに保存されている名前で)
  • 失敗した場合、書き込み用にファイルを開いて閉じようとするため、0 バイトのファイルになります。

より良いアイデアはありますか?

どんな助けでも大歓迎です、ありがとう!

PS: プログラムは MFC などの外部ライブラリを使用してはならず、組み込みの標準 C 関数のみを使用してください。

4

2 に答える 2

6

GetTempPath

一時ファイル用に指定されたディレクトリのパスを取得します。

GetTempFileName

一時ファイルの名前を作成します。一意のファイル名が生成されると、空のファイルが作成され、そのハンドルが解放されます。それ以外の場合は、ファイル名のみが生成されます。

これら 2 つは、一時ファイルの場所と名前を簡単に取得する方法を提供します。

UPD: MSDN のコード サンプル:一時ファイルの作成と使用

于 2012-03-15T09:52:55.417 に答える
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;
}
于 2017-09-20T16:58:18.977 に答える