powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / папка это файл?
25 сообщений из 230, страница 7 из 10
папка это файл?
    #39997176
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Алексей Роза 2020
пропущено...

а в паскале как?

Там разные строки были. Был вариант с хранением длины. Как в std::string. И был вариант pchar это наподобие
сишных ASCIIZ. И кажется еще было несколько библиотечных вариантов. Ну в основном использовался первый вариант.

Я помню классный был тип строки в Паскале. Он хранил длину в байте. И строки не могли быть длине 255.

А вот где данные хранились - в самом типе или в динамике я не помню.
...
Рейтинг: 0 / 0
папка это файл?
    #39997187
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Точно. 255. В информатике и выч-технике 20-го века это число - магическое.
Во многих приложениях и сетевых протоколах это число заложено как лимит.
...
Рейтинг: 0 / 0
папка это файл?
    #39997210
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
А вот где данные хранились - в самом типе или в динамике я не помню.
Байтовый массив. Позиция ноль - фактическая длина строки, дальше - собственно строка. В этом смысле - "в самом типе".
...
Рейтинг: 0 / 0
папка это файл?
    #39997213
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу сорцов du (DiskUsage) я нашел один вариант здесь

В составе GNU Core Utilities
https://github.com/coreutils/coreutils
...
Рейтинг: 0 / 0
папка это файл?
    #39997231
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНо на практике, подобные пробирующие алгоритмы не работают потому что память нужна срочно
и многим работающим потокам.

Так вопрос-то стоит не "кому нужна память", а "зачем нужна память". В попытке ответа на
него обычно вылазит "вектор на миллиард".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
папка это файл?
    #39997250
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disclaimer:
* код написан на коленке и не претендует на звание best code ever
* 100% содержит ряд багов (и я даже знаю где), но, в целом, показывает подход и пригоден для исследования производительности, и последующего устранения узких мест, т.е. служит некой отправной точкой для желающих заморочится
* не поддерживает точки монтирования/hardlinks в каталогах
* не будет работать правильно (без доработки напильником), если натравить на C:\windows или корневой каталог тома. В Windows есть каталоги, на которые у вас нет прав :)
* обработка ошибок удалена для краткости

h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
#pragma once

#define WIN32_LEAN_AND_MEAN
#include "wtypes.h"
#include "assert.h"

#include <optional>
#include <string>
#include <memory>


cpp (портянка)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
#include "test.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static constexpr std::wstring_view DOUBLE_SLASH		= L"\\\\";
static constexpr std::wstring_view LOCAL_PATH_PREFIX	= L"\\\\?\\";
static constexpr std::wstring_view UNC_PATH_PREFIX	= L"\\\\?\\unc";
static constexpr std::wstring_view UNC_SLASHED		= L"unc\\";

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace detail {

struct ff_handle_deleter
{
	using pointer = HANDLE;
	void operator()(pointer h) { ::FindClose(h); }
};

using ff_handle = std::unique_ptr<HANDLE, ff_handle_deleter>;

} // namespace detail

namespace utils {

bool is_directory_exist(const std::wstring& strPathToCheck) noexcept
{
	assert(strPathToCheck.empty() == false);
	if (strPathToCheck.empty() == false)
	{
		auto dwAttr = ::GetFileAttributesW(strPathToCheck.c_str());
		if (dwAttr != INVALID_FILE_ATTRIBUTES)
			return (dwAttr & FILE_ATTRIBUTE_DIRECTORY);
	}
	else
		::SetLastError(ERROR_BAD_PATHNAME);

	return false;
}

bool is_path_prefixed(const std::wstring& strPathToCheck) noexcept
{
	assert(strPathToCheck.empty() == false);

	constexpr auto szCompLen = LOCAL_PATH_PREFIX.size();
	return	strPathToCheck.size() >= szCompLen &&
			strPathToCheck.compare(0, szCompLen, LOCAL_PATH_PREFIX, 0, szCompLen) == 0;
}

bool is_path_unc(const std::wstring& strPathToCheck) noexcept
{
	if (is_path_prefixed(strPathToCheck))
		return ::_wcsnicmp(strPathToCheck.c_str() + 4, UNC_SLASHED.data(), UNC_SLASHED.size()) == 0;

	return	strPathToCheck.size() >= DOUBLE_SLASH.size() &&
			::wcsncmp(strPathToCheck.c_str(), DOUBLE_SLASH.data(), DOUBLE_SLASH.size()) == 0;
}

std::wstring path_add_prefix(const std::wstring& strPathToExpand)
{
	assert(strPathToExpand.empty() == false);
	if (strPathToExpand.empty() == false)
	{
		if (is_path_prefixed(strPathToExpand) == false)
		{
			if (is_path_unc(strPathToExpand))
				return std::move(std::wstring(UNC_PATH_PREFIX).append(strPathToExpand.c_str() + 1));
			
			return std::move(std::wstring(LOCAL_PATH_PREFIX).append(strPathToExpand));
		}
		return strPathToExpand;
	}
	::SetLastError(ERROR_BAD_PATHNAME);
	return {};
}

std::wstring findfile_path_builder(const std::wstring& strDirPath, const std::wstring& strSubDir, const std::wstring& strExtension)
{
	assert(strDirPath.empty() == false);
	if (strDirPath.empty())
	{
		::SetLastError(ERROR_BAD_PATHNAME);
		return {};
	}

	size_t offset = 0;
	std::wstring_view svPrefix = L"";

	if (is_path_prefixed(strDirPath) == false)
	{
		if (is_path_unc(strDirPath))
		{
			svPrefix = UNC_PATH_PREFIX;
			offset++;
		}
		else
			svPrefix = LOCAL_PATH_PREFIX;
	}

	std::wstring strMask = strSubDir.empty() ? L"*" : L"\\*";

	if (strExtension.empty() == false)
		strMask.append(strSubDir.empty() ? L"*." : L"\\*.").append(strExtension);

	if (strDirPath.back() == L'\\')
		return std::move(std::wstring(svPrefix).append(strDirPath.c_str() + offset).append(strSubDir).append(strMask));

	return std::move(std::wstring(svPrefix).append(strDirPath.c_str() + offset).append(L"\\").append(strSubDir).append(strMask));
}

} // namespace utils

std::optional<size_t> calc_directory_size(const std::wstring& strRootDir, const std::wstring& strSubDir)
{
	if (utils::is_directory_exist(strRootDir) == false)
		return {};

	size_t result = 0;
	auto strFindPath = utils::findfile_path_builder(strRootDir, strSubDir, std::wstring{});

	WIN32_FIND_DATAW wfd = {0};
	detail::ff_handle hFind(::FindFirstFileExW(strFindPath.c_str(),
							FindExInfoBasic,
							&wfd,
							FindExSearchNameMatch,
							nullptr,
							FIND_FIRST_EX_CASE_SENSITIVE|FIND_FIRST_EX_LARGE_FETCH));

	if (hFind && ::FindNextFileW(hFind.get(), &wfd))	// каталоги [.] + [..]
	{
		strFindPath.resize(strFindPath.rfind(L'\\'));

		while (::FindNextFileW(hFind.get(), &wfd))
		{
			if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if (wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
					continue;

				auto calcedSize = calc_directory_size(strFindPath, wfd.cFileName);
				if (calcedSize.has_value() == false)
				{
//					auto err = ::GetLastError();
					return {};
				}
				result += calcedSize.value();
			}
			else
			{
				ULARGE_INTEGER nFileSize = { wfd.nFileSizeLow, wfd.nFileSizeHigh };
				result += nFileSize.QuadPart;
			}
		}
	}
	
	if (::GetLastError() == ERROR_NO_MORE_FILES)
		return result;
	
//	auto err = ::GetLastError();
	return {};
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


int APIENTRY wWinMain([[maybe_unused]] HINSTANCE h, [[maybe_unused]] HINSTANCE, [[maybe_unused]] LPWSTR lpCmdLine, [[maybe_unused]] int nShowCmd)
{
	auto s = calc_directory_size(L"d:\\your_big_folder", L"");
	if (s.has_value() == false)
		return ::GetLastError();

	return s.value();
}


Диагностику снял с локального каталога на SSD, в первую очередь чтобы показать, что основная масса рассчетов/задержек приходится на kernel функцию FindFirstFile, а не на промахи кэша (но они безусловно есть, но их устранение - это экономия на спичках, имхо)

Чуть позже натравлю на каталог покрупнее по сети
...
Рейтинг: 0 / 0
папка это файл?
    #39997252
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum, спасибо большое за труд.

А в вижуалах проект должен иметь еще один файлик... эээ. Build-file? Или какой-то make-file?
...
Рейтинг: 0 / 0
папка это файл?
    #39997253
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
А в вижуалах проект должен иметь еще один файлик... эээ. Build-file? Или какой-то make-file?

достаточно просто создать пустой Win32 проект и прикрепить к нему эти файлы.
в cpp есть функция main, ее код можно уже писать как вам удобно, я привел ее для только как образец

выставить в настройках только не забудьте компиляцию с поддержкой C++17 (у меня VS2019)
...
Рейтинг: 0 / 0
папка это файл?
    #39997300
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
анализ этим же кодом более объемного каталога по сети (SMB/SSD/Windows Server 2019/LAN1Gb)

в каталоге: 78 Files, 312 237 Folders
объем: 465 MB (487 739 392 bytes)

время: 3 минуты 19 секунд !!!!
...
Рейтинг: 0 / 0
папка это файл?
    #39997310
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
время: 3 минуты 19 секунд !!!!

Судя по профилю, одно только убирание избыточной проверки на существование из calc_directory_size() сократит время на четверть.

Ну и итерации вместо рекурсии таки попробуй.
...
Рейтинг: 0 / 0
папка это файл?
    #39997311
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum, повтори эксперимент после рестарта операционки.
...
Рейтинг: 0 / 0
папка это файл?
    #39997314
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Cerebrum, повтори эксперимент после рестарта операционки.

с которой я обращаюсь на удаленку или удаленку?
...
Рейтинг: 0 / 0
папка это файл?
    #39997316
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Непонятно зачем нам проверять что директория существует? Хм. Как-то избыточно. Следующая-же транзакция
пойдет по следам и все равно проверит. Это как проверять что в БД таблица существует перед чтением.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
     if (utils::is_directory_exist(strRootDir) == false)
		return {};

	size_t result = 0;
	auto strFindPath = utils::findfile_path_builder(strRootDir, strSubDir, std::wstring{});

	WIN32_FIND_DATAW wfd = {0};
     	detail::ff_handle hFind(::FindFirstFileExW(strFindPath.c_str(),
...
Рейтинг: 0 / 0
папка это файл?
    #39997318
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
убирание избыточной проверки на существование из calc_directory_size() сократит время на четверть.

попробуем

по субъективным ощущениям (замерить мне их нечем)
Total Commander анализирует этот же каталог примерно за то же самое время как и мой код
Проводник делает это раза в 3 быстрее плюс / минус

Представьте что у вас облачный сервис, в котором клиент хранит свои данные, а ля OneDrive. Он заходит в личный кабинет, где у него должен отобразиться объем занятого его файлами места. Сайт отправляет команду вашей службе и та начинает пилить его диск в течение 3-4 минут!


За это время, сколько раз клиент, подумав что браузер завис, начнет эту операцию заново?
Короче весело...
...
Рейтинг: 0 / 0
папка это файл?
    #39997319
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
mayton
Cerebrum, повтори эксперимент после рестарта операционки.

с которой я обращаюсь на удаленку или удаленку?

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

Я имею в виду что серия экспериментов будет иметь визуальный вид улучшения результатов.
Что само по себе - фейк. В продуктовой задаче иногда бывает важен самый первый запуск
джоба. И его измерения будут эталоном.
...
Рейтинг: 0 / 0
папка это файл?
    #39997323
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Непонятно зачем нам проверять что директория существует? Хм. Как-то избыточно. Следующая-же транзакция
пойдет по следам и все равно проверит. Это как проверять что в БД таблица существует перед чтением.

с этим никто не спорит, но

представим что у нас первая итерация вызова calc_directory_size и указанный каталог не существует, получается что вместо этой проверки достанется по мозгам менеджеру памяти, который будет вынужен сначала построить нам правильную строку для FindFirstFile в utils::findfile_path_builder. То есть вся эта работа будет проведена в пустую, а если принять во внимание, что таких запросов ваша служба может получить сразу несколько или параллельно выполнять что-то тяжелое с памятью, то такое дерганиье менеджера памяти автоматически тормозит на аллокации все потоки в службе. Context Switching однако

Понятно, что надо оценить что более трудозатратно с точки зрения ОС: дернуть память пару раз или один раз сходить проверить существует ли каталог по сети.

Как уже ответил, я попробую убрать данную проверку и повторить замеры
...
Рейтинг: 0 / 0
папка это файл?
    #39997326
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
На той на которой ты делаешь дисковые операции. Я думаю что NTFS - умная система. И она - минимизирует
физические чтения областей каталогов. И этот механизм можно сбить либо размонтированием тома. И снова
монтированием. Что болезненно. И опасно. Либо перезагрузкой. Что проще.

перезагружу, не вопрос.

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

но перезагрузить попробую.
Собственно первый мой замер по сети был на холодную
...
Рейтинг: 0 / 0
папка это файл?
    #39997327
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Что болезненно. И опасно. Либо перезагрузкой. Что проще.
Ню-ню
Код: plaintext
1.
2.
3.
4.
Microsoft DiskPart version 6.1.7601
...
ONLINE      - Online an object that is currently marked as offline.
OFFLINE     - Offline an object that is currently marked as online.
...
...
Рейтинг: 0 / 0
папка это файл?
    #39997328
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
(Разводя руками)

На современных ноутах Windows часто стоит 1 системный
раздел. Вот я и исхожу из такого Пареттовского предположения.
...
Рейтинг: 0 / 0
папка это файл?
    #39997335
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
предположения
"Предположение - мать всех провалов"
Код: plaintext
1.
2.
3.
4.
5.
6.
...
    Reduces the size of the volume with focus by the specified amount. Makes
    free disk space available from unused space at the end of the volume.

Syntax:  SHRINK [DESIRED=<N>] [MINIMUM=<N>] [NOWAIT] [NOERR]
        SHRINK QUERYMAX [NOERR]
...
...
Рейтинг: 0 / 0
папка это файл?
    #39997336
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
убирание избыточной проверки на существование из calc_directory_size() сократит время на четверть.

убрал проверку, файловый сервер перезагружен
...
Рейтинг: 0 / 0
папка это файл?
    #39997339
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov, зачем нам SHRINK? Он нам в топике ненужен.
...
Рейтинг: 0 / 0
папка это файл?
    #39997340
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrumубрал проверку

Не четверть, но тоже неплохо. Теперь надо переводить на итерации и пробовать параллельное
чтение.
Вариантов два:
1) Каждый FindFirst/Next создаёт отдельный round-trip на сервер, параллельное чтение будет
рулить со страшной силой;
2) Результаты сканирования передаются по SMB пачками, параллельное чтение ухудшит ситуацию.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
папка это файл?
    #39997341
Cerebrum
За это время, сколько раз клиент, подумав что браузер завис, начнет эту операцию заново?
Короче весело...

а если он просто F5 зажмёт? Вам в другую сторону копать надо бы )
...
Рейтинг: 0 / 0
папка это файл?
    #39997343
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum, нам нужны выводы. Стало меньше. Что повлияло. Убирание exist? ИЛи ребут.
Нужно еще хотя-бы 2 измерения чтоб устаканить величину.
...
Рейтинг: 0 / 0
25 сообщений из 230, страница 7 из 10
Форумы / C++ [игнор отключен] [закрыт для гостей] / папка это файл?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]