CodingUniversity Ответов: 3

Как я могу проверить, пуст ли каталог ?


Я настраиваю свой новый код об изменении имен файлов, моя программа просто изменяет имена файлов в определенном пути, я использую библиотеку файловой системы. Моя проблема заключается в том, что когда в пути ничего нет ( в моем случае это путь загрузки), если там ничего нет, я получаю ошибку времени выполнения в случае отсутствия памяти.

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

Как я могу это сделать ?

srand(time(0));
string dirPath = "C:\\Users\\" + username() + "\\Downloads\\";
auto path = fs::path(dirPath);
auto dir = fs::recursive_directory_iterator(path);
filesystem::path currPath = path;
auto innerPaths = vector<fs::path>();
innerPaths.push_back(currPath);
int fileName = rand() % 1920;
auto currentDepthSize = dir.depth();

for (auto& block : dir)
{
    if (currentDepthSize != dir.depth())
    {
        currentDepthSize = dir.depth();
        currPath = innerPaths[currentDepthSize];
    }
    if (block.is_directory())
    {
        currentDepthSize = dir.depth();
        currPath = dir->path();
        innerPaths.push_back(currPath);
    }
    else
    {
        string filedata = (currPath.string() + to_string(fileName));
        fs::rename(block.path(), filedata);
        fileName++;
        fstream file_data(filedata);
        file_data << randomString();
        file_data.close();
    }
}


Что я уже пробовал:

Я уже пытался проверить, пуст ли каталог, но безуспешно.

Richard MacCutchan

Какая строка является проверкой пустого каталога в приведенном выше коде и что происходит при ее выполнении?

[no name]

Это тот самый случай, я не знаю, как проверить, пуст ли каталог, и если да, то просто продолжайте, я пытался использовать fs::is_empty, но безуспешно

Richard MacCutchan

См. мое решение ниже.

3 Ответов

Рейтинг:
8

Richard MacCutchan

Следующий простой код определенно работает. Приспособьте его по мере необходимости к вашим собственным требованиям.

void SimpleTest()
{
    auto mydocs = fs::path(LR"(C:\Users\ ...)"); // add a valid filesystem path here
    auto dir = fs::recursive_directory_iterator(mydocs);
    fs::path currPath = mydocs;
    
    for (auto& block : dir)
    {
        if (fs::is_directory(block.path()))
        {
            if (fs::is_empty(block.path()))
            {
                cout << block.path() << " is empty" << endl;
            }
            else
            {
                wcout << block.path() << endl;
            }
        }
    }
}


[no name]

Разве это не работает на меня, разве здесь что-то не так ?
if (currentDepthSize != dir.depth())
{
currentDepthSize = реж.глубина();
currPath = innerPaths[currentDepthSize];
}
если (блок.is_directory())
{
currentDepthSize = реж.глубина();
currPath = dir->путь();
innerPaths.push_back(currPath);
}
если (ФС::is_directory(блок.путь()))
{
если (ФС::is_empty(блок.путь()))
{
соиь <&ЛТ; блок.путь() &ЛТ;&ЛТ; "пусто" на << епси;
}
еще
{
string filedata = (currPath.string() + "\\" + to_string(fileName));
ФС::переименовать(блок.путь(), данным);
имя файла++;
fstream file_data(filedata);
file_data << randomString();
file_data.рядом();
}
}

Richard MacCutchan

Да. Блок кода, начинающийся с if (block.is_directory()). Этот directory_entry Class не содержит метода с именем is_directory(), так что я не знаю, почему это принимается вашим компилятором.

[no name]

Опять же, это не работает на меня. ):

srand(time(0));
	string dirPath = "C:\\Users\\" + username() + "\\Downloads";
	auto path = fs::path(dirPath);
	auto dir = fs::recursive_directory_iterator(path);
	filesystem::path currPath = path;
	auto innerPaths = vector<fs::path>();
	innerPaths.push_back(currPath);
	int fileName = rand() % 1920;
	auto currentDepthSize = dir.depth();

	for (auto& block : dir)
	{
		if (currentDepthSize != dir.depth())
		{
			currentDepthSize = dir.depth();
			currPath = innerPaths[currentDepthSize];
		}
		if (fs::is_directory(block.path()))
		{
			if (fs::is_empty(block.path()))
			{
				cout << block.path() << " is empty" << endl;
			}
			else
			{
				string filedata = (currPath.string() + "\\" + to_string(fileName));
				fs::rename(block.path(), filedata);
				fileName++;
				fstream file_data(filedata);
				file_data << randomString();
				file_data.close();
			}
		}
	}


Не могли бы вы просто опубликовать свой полный код ? Может быть, я что-то упускаю ):
Я так запуталась.

Richard MacCutchan

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

[no name]

Хорошо, я попытался найти свою проблему, и это эти 2 строки кода, это дает мне проблему

auto innerPaths = vector<fs::path>();
авто currentDepthSize = реж.глубина();

Как я могу это исправить ? они мне нужны, потому что для других утверждений if.

Richard MacCutchan

Извините, понятия не имею. Как я постоянно повторяю, вам нужно точно объяснить, что происходит, люди здесь не могут видеть ваш экран, поэтому понятия не имеют, что происходит.

[no name]

Омг!!!!!!!!!!!! ЭТО РАБОТАЕТ ДЛЯ МЕНЯ, СПАСИБО!!!!!!!!!!!!!!!!!

[no name]

Я не получаю никаких ошибок, но без этого и других 2-х операторов if файлы не переименовываются.

Как я могу использовать эти две строки кода, не получая никаких ошибок во время выполнения ?

Рейтинг:
2

Michael Haephrati

Вы можете использовать Функция PathIsDirectoryEmptyA (shlwapi.h) | Microsoft Docs[^]


[no name]

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

Michael Haephrati

Нашел его здесь: https://docs.w3cub.com/cpp/types/is_empty/


#include <iostream>
#include <type_traits>

структура а {};

структура B {
int m;
};

структуры с {
статический int m;
};

структура D {
виртуальный ~D();
};

Союз е {};

структура F {
[[no_unique_address]] Э э;
};

тап_п()
{
std::cout << std::boolalpha;
с std::соиь <&ЛТ; "в" &ЛТ;&ЛТ; СТД::is_empty::значение << '\n';
с std::соиь <&ЛТ; "в" &ЛТ;&ЛТ; СТД::is_empty::значение << '\n';
с std::соиь <&ЛТ; "с" &ЛТ;&ЛТ; СТД::is_empty&ЛТ;п&ГТ;::значение &ЛТ;&ЛТ; '\п';
с std::соиь <&ЛТ; "Д" &ЛТ;&ЛТ; СТД::is_empty&ЛТ;д&ГТ;::значение &ЛТ;&ЛТ; '\п';
с std::соиь <&ЛТ; "е" &ЛТ;&ЛТ; СТД::is_empty в<е&ГТ;::значение &ЛТ;&ЛТ; '\п';
с std::соиь <&ЛТ; "Ф" &ЛТ;&ЛТ; СТД::is_empty&ЛТ;Ф&ГТ;::значение &ЛТ;&ЛТ; '\п'; // результат Аби-зависимых

}

[no name]

Нет, вы используете std::is_empty, а я использую библиотеку файловой системы, поэтому функция "fs::is_empty".

И ваш код сильно отличается от моего кода, но спасибо вам за вашу помощь.

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

Mohibur Rashid

https://en.cppreference.com/w/cpp/filesystem/is_empty
это помогает?

[no name]

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

Рейтинг:
0

Richard MacCutchan

Это (как и большая часть "файловой системы") еще не является основной частью стандарта C++, поэтому вам нужно использовать экспериментальные методы. Что-то вроде:

if (experimental::filesystem::v1::is_empty(block.path))
{
    // the directory does not contain any entries
}
else
{
    // not empty so process the entries
}


[no name]

Большое спасибо! Как я могу продолжить программу, если в каталоге ничего нет?

[no name]

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

();
	innerPaths.push_back(currPath);
	int fileName = rand() % 1920;
	auto currentDepthSize = dir.depth();

	for (auto& block : dir)
	{
		if (fs::is_empty(block.path()))
		{
			exit(0);
		}
		if (currentDepthSize != dir.depth())
		{
			currentDepthSize = dir.depth();
			currPath = innerPaths[currentDepthSize];
		}
		if (block.is_directory())
		{
			currentDepthSize = dir.depth();
			currPath = dir->path();
			innerPaths.push_back(currPath);
		}
		else
		{
			string filedata = (currPath.string() + "\\" + to_string(fileName));
			fs::rename(block.path(), filedata);
			fileName++;
			fstream file_data(filedata);
			file_data << randomString();
		    file_data.close();
		}
	}">

Richard MacCutchan

Почему вы вызываете exit, если находите пустой каталог? Все, что вам нужно сделать, это проигнорировать его и продолжить цикл.

И, пожалуйста, перестаньте просто говорить "ошибка". Объясните, какую именно ошибку вы видите и в какой строке кода она возникает.

[no name]

Ладно, извини, как я могу это игнорировать ?

Richard MacCutchan

Посмотрите на образец кода, который я вам дал.

[no name]

Может, мне просто поставить перерыв в "если"?

[no name]

Хорошо, я попытался добавить перерыв, но я все еще получаю ошибку времени выполнения, эту ошибку
Возникло исключение: нарушение доступа на чтение.
_My_data было 0x48.

Это перемещает меня к информации о программе файловой системы, а не к конкретной строке моей программы.

[no name]

Извините, но ваш код не работает для меня. ):

Richard MacCutchan

Что не работает? Все, что вам нужно сделать, если элемент является каталогом, - это проверить, пуст ли он. Если он не пуст, то обрабатывайте его как обычно.

if (block.is_directory())
{
    if (!fs::is_empty(block.path()))
    {
        currentDepthSize = dir.depth();
        currPath = dir->path();
        innerPaths.push_back(currPath);
    }
}

[no name]

Спасибо, но все равно не работает на меня ):

Все еще получаю исключение this error: read access violation.
_My_data было 0x48. это означает, что на пути нет памяти.

Richard MacCutchan

Пожалуйста, перестаньте говорить "не работает", это ничего не значит. Объясните, в чем именно заключается ошибка и где она возникает. Вы внесли так много изменений в свой код, что невозможно угадать, какая строка не работает и почему.

[no name]

Новый код, который вы дали, не работает, позвольте мне объяснить, что я получаю ошибку времени выполнения.
этот тип ошибки, который означает, что в каталоге ничего нет.
нарушение доступа к чтению.
_My_data был 0x48"

И ошибка не падает ни в какую строку, просто останавливает программу .

Richard MacCutchan

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

[no name]

Так почему же код не работает, может быть, вы можете прислать мне полный код, который вы работаете на вас ? Может быть, я что-то упускаю.