Как переименовать файл из файловой системы ext4 в файловую систему ntfs в C

#c #filesystems

#c #файловые системы

Вопрос:

Есть запрос. Я всегда использую код на C (ниже) для перемещения файла из одного места в другое на том же диске (назовем его диском)

 rename(const char* old_filename, const char* new_filename);
  

Недавно мне нужно внести изменения в код, чтобы переместить его на другой диск (вызов в B-Drive). Это не работает, но я мог бы написать код для записи на этот конкретный диск (B-диск). В ходе расследования я обнаружил, что диск (A-диск), на котором я создаю результат (старый файл), находится в файловой системе ext4, но диск, на который я записываю / перемещаю, находится в NTFS (fuseblk)

Как я могу изменить свой код, чтобы переместить файл в NTFS. Я использую C в ubuntu

С уважением

———————————————————————

Новое редактирование после ответа на вызов пользователя 4581301

Это код, который я написал

 int main()
{
    std::string dirinADrive = "/home/akaa/data/test3/test_from.txt";                            // this is the parent directory
    std::string dirinBDrive = "/media/akaa/Data/GIRO_repo/working/data/test5/test_to.txt";    // this is where i want to write to
    std::string dirinCDrive = "/home/akaa/data/test3/test_to.txt";                          // this is where i want to write to
    std::string dirinDDrive = "/media/akaa/Data/GIRO_repo/working/data/test5/test_to_write.txt";

    bool ok1{std::ofstream(dirinADrive).put('a')}; // create and write to file
    bool ok2{std::ofstream(dirinDDrive).put('b')}; // create and write to file
    if (!(ok1 amp;amp; ok2))
    {
       std::perror("Error creating from.txt");
       return 1;
    }

    if (std::rename(dirinADrive.c_str(), dirinCDrive.c_str()))   // moving file to same drive
    {
        std::perror("Error renaming local");
        return 1;
    }


    if (std::rename(dirinADrive.c_str(), dirinBDrive.c_str()))   // moving file to other drive
    {
        std::perror("Error renaming other");
        return 1;
    }

    std::cout << std::ifstream(dirinBDrive).rdbuf() << 'n'; // print file
}
  

И я получил сообщение об ошибке

 Error renaming other: Invalid cross-device link
  

Итак, что такое недопустимая межустройственная ссылка??

Спасибо

Комментарии:

1. Убедитесь, что ваша система поддерживает запись в NTFS (это не должно быть проблемой, если вашему дистрибутиву Ubuntu не более 10 лет) И убедитесь, что ваша учетная запись имеет права на запись в файловую систему NTFS.

2. @user4581301: я использую ubuntu 16.04, и я полагаю, что установил разрешение на запись (как и в том же коде в другом месте, я написал функцию для создания файла). Я просто не знаю, что пошло не так

3. Вызовите perror in после rename сбоя и посмотрите, содержит ли возвращаемое сообщение об ошибке какую-либо полезную информацию. Подумайте о написании простой программы, которая ничего не делает, кроме как пытается переместить файл. Если это также не удается, опубликуйте эту простую программу (хотя бы для того, чтобы вы могли сказать: «Я получил MCVE прямо здесь, панк».) Если это не сработает, привет, больше информации для работы.

4. @пользователь4581301. Отредактировал мой вопрос, чтобы включить ваши комментарии

5. Это сообщение означает, что по какой-то причине вы не можете переместить файл с диска a на диск b. Не уверен, почему это так, но, вероятно, это связано с тем, что вы не можете сделать перемещение атомарным. Посмотрите, можете ли вы выполнить перемещение из командной строки. Если вы не можете, вы можете получить лучшую помощь у суперпользователя , но поскольку вы перемещаетесь с одного диска на другой, вы все равно закончите копирование. Если перемещение завершится неудачей, вернитесь к копированию и удалите оригинал.

Ответ №1:

Вы не можете использовать rename разные файловые системы, потому что данные должны быть скопированы (а выполнение одним системным вызовом произвольного объема работы проблематично даже без проблем с атомарностью). Вам действительно нужно открыть исходный файл и конечный файл и записать содержимое одного в другой. Примените любые атрибуты, которые вы хотите сохранить (например, с stat помощью и chmod ), затем удалите исходный файл, если хотите.

В C 17 большая часть этого была упакована как std::filesystem::copy_file . (Есть также std::filesystem::rename , но это не лучше, чем std::rename для этого случая.)