Почему записи, кроме того, заказывают в.Net Dictionary?

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

blockquote>

. Официальный сайт libcurl - https://curl.haxx.se/libcurl/ , и, как вы можете видеть enter image description here

, здесь есть раздел с примерами. находится по адресу https://curl.haxx.se/libcurl/c/example.html с множеством примеров. Один из самых простых примеров находится по адресу https://curl.haxx.se/libcurl/c/simple.html , а конкретный простой пример «загрузки файла» можно найти здесь: https://curl.haxx.se/libcurl/c/url2file.html

/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/ 
/* 
 * Download a given URL into a local file named page.out.
 * 
 */ 

#include 
#include 
#include 

#include 

static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
  size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
  return written;
}

int main(int argc, char *argv[])
{
  CURL *curl_handle;
  static const char *pagefilename = "page.out";
  FILE *pagefile;

  if(argc < 2) {
    printf("Usage: %s \n", argv[0]);
    return 1;
  }

  curl_global_init(CURL_GLOBAL_ALL);

  /* init the curl session */ 
  curl_handle = curl_easy_init();

  /* set URL to get here */ 
  curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]);

  /* Switch on full protocol/debug output while testing */ 
  curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);

  /* disable progress meter, set to 0L to enable and disable debug output */ 
  curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);

  /* send all data to this function  */ 
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

  /* open the file */ 
  pagefile = fopen(pagefilename, "wb");
  if(pagefile) {

    /* write the page body to this file handle */ 
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);

    /* get it! */ 
    curl_easy_perform(curl_handle);

    /* close the header file */ 
    fclose(pagefile);
  }

  /* cleanup curl stuff */ 
  curl_easy_cleanup(curl_handle);

  curl_global_cleanup();

  return 0;
}
23
задан Daniel Magliola 30 September 2008 в 18:58
поделиться

11 ответов

Если вы используете .NET Reflector в библиотеках классов 3.5, вы можете увидеть, что реализация Dictionary фактически сохраняет элементы в массиве (размер которого изменяется по мере необходимости) и хеширует индексы в этот массив . При получении ключей он полностью игнорирует хеш-таблицу и выполняет итерацию по массиву элементов. По этой причине вы увидите описанное вами поведение, поскольку новые элементы добавляются в конец массива. Похоже, если вы сделаете следующее:

add 1
add 2
add 3
add 4
remove 2
add 5

, вы вернетесь 1 5 3 4, потому что он повторно использует пустые слоты.

Важно отметить, как и многие другие, вы не можете рассчитывать на такое поведение в будущем (или прошлые) релизы. Если вы хотите, чтобы ваш словарь был отсортирован, для этой цели существует класс SortedDictionary .

40
ответ дан 29 November 2019 в 01:18
поделиться

Вы не можете рассчитывать на это поведение, но это не удивительно.

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

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

5
ответ дан 29 November 2019 в 01:18
поделиться

Я думаю, что это происходит из старой версии .NET 1.1, где у вас было два вида словарей «ListDictionary» и «HybridDictionary». ListDictionary был словарем, реализованным внутри как упорядоченный список, и был рекомендован для «небольших наборов записей». Затем у вас был HybridDictionary , который изначально был внутренне организован как список, но если он вырос больше настраиваемого порога, он стал бы хеш-таблицей. Это было сделано потому, что исторически правильные словари, основанные на хэше, считались дорогими. Сейчас дни, которые не имеют особого смысла, но я полагаю, что .NET просто основал свой новый универсальный класс Dictionary на старом HybridDictionary.

Примечание : В любом случае, как уже сказал кто-то другой, вы не должны никогда рассчитывать на порядок словаря для чего-либо

2
ответ дан 29 November 2019 в 01:18
поделиться

Кавычка от MSDN:

порядок ключей в Dictionary< (< (TKey, TValue>)>).KeyCollection является неуказанным, но это - тот же порядок как присваиваемые значения в Dictionary< (< (TKey, TValue>)>).ValueCollection возвращенный Dictionary< (< (TKey, TValue>)>).Values свойство.

1
ответ дан 29 November 2019 в 01:18
поделиться

С какими ключами Вы добавляли в Вашем тесте, и в какой порядок?

1
ответ дан 29 November 2019 в 01:18
поделиться

Ваши записи могли бы все быть в том же блоке хеша в словаре. Каждый блок является, вероятно, списком записей в блоке. Это объяснило бы записи, возвращающиеся в порядке.

1
ответ дан 29 November 2019 в 01:18
поделиться

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

0
ответ дан 29 November 2019 в 01:18
поделиться

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

Добавляют 100 или 1 000 объектов и видят, находятся ли они все еще в том же порядке.

0
ответ дан 29 November 2019 в 01:18
поделиться

Я ненавижу этот вид "по замыслу" функциональности Я думаю, что, давая вашему классу такое общее имя, как «Словарь», он также должен вести себя «как обычно ожидается». Например, std :: map всегда сохраняет отсортированные значения ключей.

Редактировать: очевидно, решение состоит в том, чтобы использовать SortedDictionary, который ведет себя подобно std :: map.

0
ответ дан 29 November 2019 в 01:18
поделиться

Словарь извлекает элементы в порядке хеширования. Тот факт, что они вышли в порядке вставки, был полным совпадением.

Документация MSDN гласит:

Порядок ключей в KeyCollection не указан, но он совпадает с порядком связанных значений в ValueCollection, возвращаемых свойством Values.

8
ответ дан 29 November 2019 в 01:18
поделиться

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

Цель словаря или хеш-таблицы состоит в том, чтобы иметь возможность эффективно искать конкретное значение по известному ключу. Внутренняя реализация любого словаря или хеш-таблицы должна обеспечивать эту эффективность при поиске, но не должна обеспечивать какого-либо конкретного поведения в отношении перечислений или «для каждого» итерации типа для значений или ключей.

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

-1
ответ дан 29 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

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