Задать вопрос
EgoRusMarch
@EgoRusMarch
C++ Developer

Что не так с ограничением максимальной длины имени файла?

В общем, нашёл, что под Windows ограничение на 255 символов, а под Linux на 255 байт, и написал такой код для копирования файлов с переименованием (там в имени сохраняются координаты прямоугольиков, и их может быть много, не лучшее решение, но это не я придумал).

std::string filename = current_image->path().stem().string();

        #if OS == LINUX
        for (const auto& ch : filename)
            if (!std::isalpha(ch) && !std::isdigit(ch) &&
                ch != ' ' && ch != '.' &&ch != '-' && ch != '_')
            {
                QMessageBox::warning(
                    this, "Warning",
                    "Файл не будет сохранён, т.к. содержит недопустимые символы в "
                    "своём имени.\nДопустимые символы: латинские буквы, цифры, "
                    "пробел, точка, '-' и '_'."
                );

                goto filename_invalidity;
            }
        #endif

        for (const auto& rect : rect_grabber->getRects())
        {
            std::string rect_data = "_["
                + std::to_string(rect.x()) + "," + std::to_string(rect.y()) + ","
                + std::to_string(rect.width()) + "," + std::to_string(rect.height()) + ","
                + rect.getType() + "]";

            if (filename.size() + rect_data.size()
                    + current_image->path().extension().string().size() <= 255)
            {
                filename += rect_data;
            }
            else
            {
                QMessageBox::warning(
                    this, "Warning",
                    "Имя файла превысило максимально допустимую длину (255 символов)."
                    " Часть данных разметки не будет сохранена в имени файла."
                );

                break;
            }
        }

        filename += current_image->path().extension().string();

        fs::copy(current_image->path(),fs::path{load_window->getOutDirPath()/filename});
    }

Всё это падает сразу после вывода второго QMessageBox::warning, т.е. при сохранении с переименованием. Но сам алгоритм исключает ситуацию, что будет сохранено более 255 символов (включая расширение с точкой). Что не так?
  • Вопрос задан
  • 2077 просмотров
Подписаться 1 Простой 13 комментариев
Пригласить эксперта
Ответы на вопрос 3
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Под Виндоуз ограничение 32килобайта. Ищите соответствующие функции, кстати и в линуксе такое. Плюс есть дкраукая шуточка создавать папку переходить в неё и создавать папку. В общем выбирают все дескрипторы на файловой системе, и удалить можно только спустившись вниз и удаляя папки переходя вверх
Ответ написан
Ziptar
@Ziptar
Дилетант широкого профиля
В общем, нашёл, что под Windows ограничение на 255 символов

Не в "windows", а конкретно в проводнике. NTFS отлично работает и с гораздо более длинными путями - ей пофиг. А вот проводник не умеет. Что характерно - некорые виндовые API для приложений игнорируют это ограничение, в результате чего приложение может сохранить файл с более длинным путём. Потом получается неприятно.
Ответ написан
pindschik
@pindschik
ФЫВА ОЛДЖ
Поправка - этот глюк в 255 символов - не только имя, но и весь путь к нему. Но опять же - никакого ограничения нет - это косяк дефолтного проводника и только.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы