Как я могу удалить файл после его закрытия в C ++ в Linux? - PullRequest
8 голосов
/ 05 июля 2010

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

Ответы [ 6 ]

10 голосов
/ 05 июля 2010

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

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

3 голосов
/ 05 июля 2010
2 голосов
/ 05 июля 2010

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

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

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

0 голосов
/ 05 июля 2010

Я думаю, что вам нужно расширить понятие «закрытие файла» за пределы 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 :: удалить, как предполагает Том).

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

0 голосов
/ 05 июля 2010

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

#include <unistd.h>

int unlink(const char *pathname); 

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

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

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

0 голосов
/ 05 июля 2010

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

Может быть boost :: filesystem :: remove ?

bool remove( const path & ph );

Условие:! Ph.empty ()

Возвращает: значение существует (ph) до создания Постусловие.

Постусловие:! Существует (тел.)

Броски: если ph.empty () || (Существует (Ph) && is_directory (ph) &&! is_empty (ph)). См. Обоснование пустого пути.

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

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

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

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

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...