Как удалить файл после его закрытия в C++ на Linux?

Я хочу, чтобы файл будет удален с диска только тогда, когда он закрыт. До этого момента другие процессы должны иметь возможность видеть файл на диске и читать его содержимое, но в конечном итоге после закрытия файла он должен быть удален с диска и больше не виден на диске другим процессам.

6 ответов


откройте Файл, затем удалите его пока Она открыта. Другие процессы смогут использовать файл, но как только все дескрипторы файла будут закрыты, он будет удален.

Edit: основываясь на комментариях, добавленных WilliamKF позже, это не выполнит то, что он хочет-он будет держать сам файл вокруг, пока все дескрипторы к нему не будут закрыты,но запись каталога для имени файла исчезнет, как только вы позвоните unlink/remove.



открытые файлы в Unix подсчитываются по ссылкам. Каждый open(2) увеличивает счетчик, каждые close(2) уменьшает его. Счетчик является общим для всех процессов в системе.

тут ссылка графа для дискового файла. Новый файл получает счет. Количество увеличивается на link(2) системный вызов. The unlink(2) уменьшает его. Файл удаляется из файловой системы, когда это число падает до нуля.

в единственный способ выполнить то, что вы просите, - открыть файл в одном процессе, а затем unlink(2) его. Другие процессы смогут open(2) или stat(2) это между open(2) и unlink(2). Если файл имел только одну ссылку, он будет удален, когда все процессы что у него открыто, закройте его.


использовать unlink

#include <unistd.h>

int unlink(const char *pathname); 

unlink() удаляет имя из файловая система. Если это имя было последней ссылка на файл, а не процессы Файл Открыть файл удаляется и пространство, которое он занимает, доступно для повторного использования.

Если имя было последней ссылкой на файл, но любые процессы все еще имеют Файл Открыть файл останется в существование до последнего файла дескриптор, ссылающийся на него закрытый.

Если имя ссылается на символ ссылка ссылка удаляется.

Если имя указывает на сокет, FIFO или устройство имя для него удаляется но процессы, которые имеют объект open может продолжать использовать его.


Не уверен, но можно попробовать удалить, но это больше похоже на c-стиль.

может быть boost::файловая система:: удалить?

bool remove( const path & ph );

условие: !рН.пустой()

Returns: значение exists( ph ) до создания постусловие.

Postcondition:!существует( рН )

броски: если ph.пустой () / / (существует (ph) && is_directory (ph) && !is_empty (ph)). Увидеть пустые обоснование пути.

Примечание: символические ссылки сами по себе удалил, а не то, что они указывают к удалению.

обоснование: не бросает, когда !существует (ph), потому что не бросает:

работает правильно, если ph болтается символическая ссылка. Немного легк-к-польза для много Общая польза случаи. Немного выше уровня потому что это подразумевает использование семантика постусловий, а не семантика эффектов, которая была бы указано в несколько ниже уровня условия взаимодействия с операционная система. Однако существует небольшое снижение безопасности, потому что некоторые ошибки будут проскальзывать, иначе был бы обнаружен. Например, имя пути, написанное с ошибкой долгое время оставалась незамеченной.

начальная версия библиотеки бросил исключение, когда путь сделал не существует; он был изменен, чтобы отразить жалобы пользователей.

Вы можете создать класс-оболочку, которая подсчитывает ссылки, используя один из вышеуказанных методов для удаления de файла .

class MyFileClass{

    static unsigned _count;
 public:
    MyFileClass(std::string& path){
     //open file with path
     _count++;
    }

    //other methods

    ~MyFileClass(){

        if (! (--_count)){

          //delete file
        }

     }

    };

   unsigned MyFileClass::_count = 0; //elsewhere

Я думаю, вам нужно расширить свое понятие "закрытие файла" за пределы fclose или std::fstream::close к тому, что вы намереваетесь сделать. Это может быть так же просто, как

class MyFile : public std::fstream {
  std::string filename;
public:
  MyFile(const std::string &fname) : std::fstream(fname), filename(fname) {}
  ~MyFile() { unlink(filename); }
}

или это может быть нечто гораздо более сложное. Насколько я знаю, это может быть даже намного проще – если вы закрываете файлы только в одном или двух местах в своем коде, лучше всего просто unlink файл там (или используйте boost::filesystem:: remove, как предлагает том).

OTOH, если все, что вы хотите достичь это то, что процессы, запущенные из вашего процесса, могут использовать файл, вам может не понадобиться держать его на диске вообще. forkпроцессы ed наследуют открытые файлы. Не забудьте dup их, чтобы поиск в ребенке не влиял на положение в родителе или наоборот.