#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
для этого случая.)