Как MediaWiki составляет каналы передачи изображения?

Обычно вы не должны делать это с std::copy_n, что предполагает, что предоставленный итератор при увеличении n раз остается в силе:

Копирует точно count значения от диапазона, начинающегося в first до диапазона, начинающегося в result. Формально для каждого неотрицательного целого числа i < n выполняется *(result + i) = *(first + i).

( статья на cppreference.com на std::copy_n ) sup>

blockquote>

Если вы можете это гарантировать, тогда хорошо, но обычно с std::cin ] это невозможно. Вы можете довольно просто разыменовать недопустимый итератор:

Построенный по умолчанию std::istream_iterator известен как итератор конца потока. Когда действительный std::istream_iterator достигает конца основного потока, он становится равным итератору конца потока. Разыменование или инкремент в дальнейшем вызывает неопределенное поведение.

( статья на cppreference.com на std::istream_iterator ) sup>

blockquote>

Вы в значительной степени там со своим циклом, хотя я бы вероятно, используйте более сильное условие завершения, чтобы избежать избыточного чтения из «мертвого» потока:

vector v(n);
for(vector::size_type i = 0; i < n; i++)
    if (!cin >> v[i])
       break;

Я бы соблазнился на самом деле обернуть это во что-то вроде std::copy_n, но принимает полный «диапазон», чей границы могут быть проверены в дополнение к подсчету от 0 до N .

Реализация может выглядеть следующим образом:

template
OutputIt copy_atmost_n(InputIt first, InputIt last, Size count, OutputIt result)
{
   for (Size i = 0; i < count && first != last; ++i)
      *result++ = *first++;
   return result;
}

Вы бы использовали это так:

copy_atmost_n(
   std::istream_iterator(std::cin),
   std::istream_iterator(),
   N,
   std::back_inserter(v)
);

Теперь вы получаете M элементов, где [1122 ] M - это либо количество предоставленных входов, либо N , в зависимости от того, что меньше.

( живое демо )

8
задан RobEarl 3 August 2013 в 08:11
поделиться

3 ответа

Один возможный путь состоял бы в том, чтобы вычислить подпись MD5 файла (или идентификатор файла в базе данных) и затем создать/найти путь на основе этого.

Например, скажите, что мы получаем подпись MD5 как "1ff8a7b5dc7a7d1f0ed65aaa29c04b1e"

Путь мог бы быть похожим на "/1f/f" или "/1f/ff/8a"

Причина состоит в том, что Вы не хотите иметь все файлы в 1 папке, и Вы хотите иметь способность "разделить" их через различные серверы или SAN или безотносительно equally-spread-out способом.

Подпись MD5 является строкой 16 "шестнадцатеричных" символов. Таким образом, наш пример "/1f/ff/8a" дает нам 256*256*256 папок, чтобы хранить файлы в. Это должно быть достаточно для кого-либо :)


Обновление, из-за популярного спроса:

ОТМЕТЬТЕ - я просто понял, что мы говорим конкретно о том, как MediaWiki делает это. Это не теперь MediaWiki, делает это, но иначе в котором это, возможно, было сделано.

"Подписью MD5" я означаю делать что-то вроде этого (примеры кода в Perl):

use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );

$sig является теперь 32 алфавитно-цифровыми символами долго: "1ff8a7b5dc7a7d1f0ed65aaa29c04b1e"

Затем создайте структуру папок как это:

my $path = '/usr/local/media';
map { mkdir($path, 0666); $path .= "/$_" } $sig =~ m/^(..)(..)(..)/;
open my $ofh, '>', "$path/$sig"
  or die "Cannot open '$path/$sig' for writing: $!";
print $ofh "File contents";
close($ofh);

Структура папок похожа

/
  usr/
    local/
      media/
        1f/
          f8/
            a7/
              1ff8a7b5dc7a7d1f0ed65aaa29c04b1e
2
ответ дан 5 December 2019 в 09:26
поделиться

Принятый ответ является неправильным:

  • Сумма MD5 строки является 32 шестнадцатеричными символами (128 битов), не 16
  • Путь к файлу вычисляется от суммы MD5 имени файла, не содержания самого файла
  • Первый каталог в пути является первым символом, и второй каталог является первыми и вторыми символами. Путь к каталогу не является комбинацией первых 3 или 6 символов.

Сумма MD5 'Herbs.jpg' является fceaa5e7250d5036ad8cede5ce7d32d6. Первыми 2 символами является 'ФК', давая путь к файлу f/fc/, который является тем, что дано в примере.

12
ответ дан 5 December 2019 в 09:26
поделиться

В PHP можно вызвать следующую функцию для получения URL. Можно хотеть посмотреть на код php, чтобы выяснить, как они вычисляют путь.

$url = wfFindFile(Title::makeTitle(NS_IMAGE, $fileName))->getURL();
4
ответ дан 5 December 2019 в 09:26
поделиться
Другие вопросы по тегам:

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