Хранение большого количества изображений

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

public class TestedClass {

    interface PojoFactory { Pojo getNewPojo(); }

    private final PojoFactory factory;

    /** For use in production - nothing needs to change. */
    public TestedClass() {
        this.factory = new PojoFactory() {
            @Override
            public Pojo getNewPojo() {
                return new Pojo();
            }
        };
    }

    /** For use in testing - provide a pojo factory. */
    public TestedClass(PojoFactory factory) {
        this.factory = factory;
    }

    public void doSomething() {
        Pojo pojo = this.factory.getNewPojo();
        anythingCouldHappen(pojo);
    }
}

При этом ваше тестирование, подтверждение и проверка вызовов объекта Pojo просты:

public  void testSomething() {
    Pojo testPojo = new Pojo();
    TestedClass target = new TestedClass(new TestedClass.PojoFactory() {
                @Override
                public Pojo getNewPojo() {
                    return testPojo;
                }
            });
    target.doSomething();
    assertThat(testPojo.isLifeStillBeautiful(), is(true));
}

Единственный недостаток этого подхода потенциально может возникнуть, если TestClass имеет несколько конструкторов, которые вам придется дублировать с дополнительным параметром.

По причинам SOLID вы, вероятно, захотите поместить интерфейс PojoFactory в класс Pojo, а также на фабрику.

public class Pojo {

    interface PojoFactory { Pojo getNewPojo(); }

    public static final PojoFactory productionFactory = 
        new PojoFactory() {
            @Override 
            public Pojo getNewPojo() {
                return new Pojo();
            }
        };
48
задан Pete Kirkham 24 March 2009 в 12:22
поделиться

11 ответов

У нас была подобная проблема в прошлом. И найденный хорошим решением:

  • Дают каждому изображению уникальный гуид.
  • Создают запись базы данных для каждого изображения, содержащего имя, местоположение, гуид и возможное местоположение изображений sub (миниатюры, reducedsize, и т.д.).
  • Использование первое (один или два) символы гуида для определения папки верхнего уровня.
  • , Если папки имеют слишком много файлы, разделите снова. Обновите ссылки, и Вы готовы пойти.
  • , Если количество файлов и доступов слишком высоко, можно распространить папки по различным файловым серверам.

Мы испытали то использование гуидов, Вы получаете более или менее универсальное подразделение. И это работало как очарование.

Ссылки, которые могли бы помочь генерировать уникальный идентификатор:

46
ответ дан Aaron Digulla 7 November 2019 в 22:33
поделиться

Посмотрите на файловую систему XFS. Он поддерживает неограниченное количество файлов, и Linux поддерживает это. http://oss.sgi.com/projects/xfs/papers/xfs_usenix/index.html

2
ответ дан 7 November 2019 в 12:33
поделиться

При сохранении файлов, связанных с идентификаторами auto_increment, я использую что-то вроде следующего, которое создает три уровня каталогов, каждый из которых состоит из 1000 каталогов и 100 файлов в каждом каталоге третьего уровня. Это поддерживает ~ 100 миллиардов файлов.

если $ id = 99532455444, то следующее возвращает / 995/324/554/44

function getFileDirectory($id) {
    $level1 = ($id / 100000000) % 100000000;
    $level2 = (($id - $level1 * 100000000) / 100000) % 100000;
    $level3 = (($id - ($level1 * 100000000) - ($level2 * 100000)) / 100) % 1000;
    $file   = $id - (($level1 * 100000000) + ($level2 * 100000) + ($level3 * 100));

    return '/' . sprintf("%03d", $level1)
         . '/' . sprintf("%03d", $level2)
         . '/' . sprintf("%03d", $level3)
         . '/' . $file;
}
5
ответ дан 7 November 2019 в 12:33
поделиться

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

Это предположение.

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

http://www.databasesandlife.com/flat-directories/

7
ответ дан 7 November 2019 в 12:33
поделиться

Я работал над Системой электронного документооборота несколько лет назад, и мы сделали в значительной степени что Gamecat и предложенный wic.

таким образом, присвойте каждому изображению уникальный идентификатор и использование что получить относительный путь к файлу изображения. Мы использовали MOD, подобный тому, какой предложенный wic, но мы позволили 1 024 папки/файла на каждом уровне с 3 уровнями, таким образом, мы могли поддерживать файлы 1G.

Мы сняли изоляцию с расширения из файлов как бы то ни было. Записи DB содержали Тип MIME, таким образом расширение было не нужно.

я не рекомендовал бы хранить полный URL в записи DB, только идентификатор Изображения. При хранении URL, Вы не можете переместить или реструктурировать свое устройство хранения данных, не преобразовывая Ваш DB. Относительный URL был бы в порядке начиная с того способа, которым можно, по крайней мере, переместить репозиторий образов вокруг, но Вы получите больше гибкости, если Вы просто сохраните идентификатор и получите URL.

кроме того, я не рекомендовал бы позволить прямые ссылки Вашим файлам изображений от сети. Вместо этого предоставьте URL программе серверной стороны (например, Сервлет Java), с идентификатором Изображения, предоставляемым в Запросе URL (http://url.com/GetImage?imageID=1234).

сервлет может использовать тот идентификатор, чтобы искать запись DB, определить Тип MIME, получить фактическое местоположение, проверить на ограничения безопасности, вход, и т.д.

11
ответ дан Clayton 7 November 2019 в 22:33
поделиться

Я обычно просто использую числовой идентификатор базы данных (auto_increment) и затем использую modulu (%) оператор для выяснения, куда поместить файл. Простой и масштабируемый. Например, путь для обработки изображений с идентификатором 12345 мог быть создан как это:

12345 % 100 = 45
12345 % 1000 = 345

Заканчивается в:

/home/joe/images/345/45/12345.png

Или что-то как этот.

при использовании Linux и ext3 и файловой системы необходимо знать, что существуют пределы количеству каталогов и файлов, которые Вы можете иметь в каталоге. Предел 32000 для директоров, таким образом, необходимо всегда стремиться поддержать число на низком уровне директоров.

8
ответ дан Martin Wickman 7 November 2019 в 22:33
поделиться

Вы могли alawys иметь столбец DateTime в таблице и затем хранить их в папках, названных после месяца, года или даже месяца, дня, года изображения, где добавлено к таблице.

Пример

  1. 2009
  2. -01
  3. - 01
  4. - 02
  5. - 03
  6. - 31

этот путь Вы заканчиваете без более тогда 3 папок глубоко.

1
ответ дан Mike Geise 7 November 2019 в 22:33
поделиться

Можно проверить stratey, используемый Apple iPod для хранения, это - мультимедийный контент. Существуют папки на одном уровне глубины и файлов с заголовками той же ширины. Я полагаю, что парни Apple инвестировали много времени в тестировании их решения, таким образом, это может принести некоторое мгновенное преимущество Вам.

0
ответ дан Boris Pavlović 7 November 2019 в 22:33
поделиться

Используйте иерархию файловой системы. Идентификатор Ваши изображения с помощью чего-то как 001/002/003/004.jpg был бы очень полезен. Разделение является другой историей, все же. Могла быть случайная, базирующаяся дата создания на основе содержимого, и т.д. Действительно зависит от того, каково Ваше приложение.

0
ответ дан PolyThinker 7 November 2019 в 22:33
поделиться

Можно сохранить изображения в базе данных как блобы ( varbinary для mssql). Тем путем Вы не должны волноваться об устройстве хранения данных или структуре каталогов. Единственный недостаток - то, что Вы не можете легко просмотреть файлы, но это было бы твердо в сбалансированном дереве каталогов так или иначе.

0
ответ дан Mats Fredriksson 7 November 2019 в 22:33
поделиться

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

0
ответ дан Keltia 7 November 2019 в 22:33
поделиться
Другие вопросы по тегам:

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