Яка найкраща практика називати завантажені зображення?


15

Припустимо, у мене в веб-програмі є форма, в яку користувачі можуть завантажувати зображення профілю.

У мене мало вимог щодо розміру файлу, розмірів тощо, але коли користувач завантажує зображення, як я повинен називати їх у своїй системі? Я припускаю, що це повинно бути послідовним, а також унікальним.

Можливо, GUID?

a5c627bedc3c44b7ae7c06a44fb3fcf8.jpg

Часова позначка?

129899740140465735.jpg

Хеш? Наприклад: md5

b1a9acaf295cf14ffbc5b6538294562c.jpg

Чи є стандартний чи рекомендований спосіб це зробити?


7
Якщо ваша мета - зберігати лише одне зображення профілю на користувача, дехто скаже, що очевидним вибором буде назвати файл таким же, як ідентифікатор користувача.
Алан Барбер

мітка часу не є хорошою ідеєю, тому що DateTime.Now оновлюється лише кожні 15 мс. Є велика ймовірність зіткнення, наприклад, під час масового завантаження, запитів у черзі тощо.
jhexp

Відповіді:


27

Вам слід постаратися досягти двох цілей: унікальності та корисності.

Використання GUID гарантує унікальність, але одного дня файли можуть відірватися від їх початкового джерела, і тоді у вас виникнуть проблеми.

Моє типове рішення - вбудувати важливу інформацію в ім'я файлу, наприклад, UserID (якщо він належить користувачеві) або дата та час завантаження (якщо це важливо), або ім'я файлу, яке використовується для його завантаження.

Це дійсно може зберегти вашу шкіру одного дня, коли інформація, вбудована у ім’я файлу, дозволяє вам, наприклад, відновитись із помилки або випадкового видалення записів. Якщо у вас є лише GUID-файли, і ви втратите каталог, вас чекає робота по прибиранню роботи.

Наприклад, якщо файл "Моє свято: Флорида 23.jpg" завантажено користувачем ID ID 98765, 2013/04/04 в 12:51:23, я б назвав це приблизно так, додавши випадковий рядок ad8a7dsf9:

20130404125123-ad8a7dsf9-98765-my-holiday-florida-23.jpg

  • Унікальність забезпечується датою та часом, а також випадковим рядком (за умови, що він належним чином випадковий з / dev / urandom або CryptGenRandom.
  • Якщо файл коли-небудь від'єднується, ви можете визначити користувача, дату та час та назву.
  • Все складено в малі регістри, і все, що не буквено-цифрове, видаляється і замінюється тире, що робить ім'я файлу легким в обробці за допомогою простих інструментів (наприклад, пробілів, які не можуть плутати погано написані сценарії, немає колонок або інших символів, заборонених у деяких файлових системах , і так далі).

7
Для ведення господарства я рекомендую створити окремі каталоги на користувальницьку ID, так що якщо ви видалите користувача, вам не доведеться полювати за всіма їх зображеннями. - так98765/20130404125123-ad8a7dsf9-my-holiday-florida-23.jpg
Шадур

1
Теоретично унікальність не забезпечується випадковим рядком.
Колюня

4
@Kolyuny, це правда, в тому сенсі, що гарантована глобальна унікальність - це не властивість, яку мають навіть GUID в реальному житті (навіть путівки v1 розбиті через видачу дублікатів MAC-адрес). Все, що можна отримати, - це статистична ймовірність унікальності. Але ви можете забезпечити унікальність, перевіривши, чи файл вже існує (атомно за CreateFileдопомогою CREATE_NEW), та використовуючи різні випадковість, якщо він є.
Бен

"Все складено в малі регістри, і все, що не буквено-цифрове, видаляється і замінюється тире", я б зберігав це змішаним регістром,
видаляю

4

Ви не хочете напружувати додатки (наприклад, Провідник) і робити його збоєм під час відкриття каталогу. Хоча навряд чи ви будете наголошувати на фактичній файловій системі, вам потрібно врахувати це, якщо ви збираєтеся зберігати тисячі файлів.

Якщо ви розраховуєте зберегти тисячі файлів, я пропоную розділити їх на папки. Наприклад upload\silo001, upload\silo002і т. Д. Ви можете або збалансувати свої файли, або почекати, поки папка потрапить на певну кількість файлів, а потім створити інший.

Що стосується імен, я завжди називаю файл із GUID, оскільки він унікальний у всьому світі. Я витягую розширення з завантаження і встановлюю розширення файлу у відповідність, але власне ім'я встановлюється з нового Guid.

Якщо ви робите це спільно з RDBMS і маєте кілька категорій, тобто продукти, категорії тощо, які ви могли мати upload\products, upload\categoriesтощо, і ви можете використовувати ідентифікатор рядка як ім'я файлу.

З точки зору кращих практик я теж заглянув у минуле і нічого не знайшов. Я придумав вищесказане під час обговорення з деякими моїми розробниками.


2

В одному з рішень, над якими я працював років тому, ми зробили це: підпапки для частини ідентифікатора користувача, тому якщо ваш ідентифікатор користувача був 232950192

ми матимемо підпапки зображення / 23/29/50/192/232950192

в остаточній папці є папки для альбунів та профілів і т.п.

Але ми також зберігаємо все в базі даних і зберігаємо його у файловій системі для швидкого доступу до веб-сервера (який також має кешування)

У будь-якому випадку остаточне зображення матиме оригінальну назву зображення. Нам не потрібно було зберігати версії. Але для чого можна зберегти більше підпапок під кінцевими назвами альбомів або в базі даних з ідентифікатором версії. потрібно думати це через те, що як тільки перейти до виробництва, було б важко змінити речі без трудомістких та помилок, схильних до помилок у поточній структурі

Створити підпапку в Java дуже легко і створити в ній файл:

    File folder = new File(pathwithslashes);// like "images/23/29/50/192/232950192"
    folder.mkdirs();
    File imgFile = new File(folder, name);
    //Now get output stream etc

Щоб отримати штамп дати у підпапках: SimpleDateFormat sdf = new SimpleDateFormat ("/ yyyy / MM / dd /"); pathwithslashes = pathwithslashes + sdf.format (зараз); // зараз - папка util.Date File = new File (pathwithslashes);

Dot net /programming/5482230/c-sharp-equivalent-of-javas-mkdirs


+1 за пропозицію вкладених каталогів. Я думаю, що це важливо враховувати, оскільки різні файлові системи можуть зіткнутися з проблемами продуктивності, коли папки містять "занадто багато" файлів: stackoverflow.com/questions/197162/… , support.microsoft.com/kb/130694/en-us тощо.
deizel

1
так, на іншій системі було одне зависання веб-сервера, коли ми намагалися запустити rmdir на aa dir, який мав понад 400 000 файлів. у нас було більше таких папок. тож використовувала користувальницьку програму, яка називала dir / p, щоб отримати кілька файлів, які потрібно видалити за один раз. зайняло декілька годин, але без часу :)
tgkprog

1

Я рекомендую використовувати тільки md5 або що-небудь концептуально еквівалентне. Перейменовуючи файли за допомогою дайджесту вмісту, ви надаєте не лише унікальність (завжди кешуйте зображення настільки довго, наскільки це можливо, і перейменовуючи на основі вмісту, ну, при правильному, ви можете кешувати зображення практично назавжди).

Крім того, це не велика справа, але, тим не менш, це не чистий гіпотетичний випадок, коли різні користувачі завантажують абсолютно однакові зображення. Щойно з коробки у вас буде невелика оптимізація зберігання даних.

Щодо всього іншого, що пропонується: як на мене, я є сильним противником зберігання будь -якої допоміжної інформації у назві файлу. Коли я був набагато молодший (і трохи стрункіший :), я був розробником Perl і мав сумнівну звичку зберігати стільки допоміжної інформації у назві файлів, скільки дозволяв мені здоровий глузд, оскільки особливості шаблону рядка Perl є приголомшливими. І я прийшов до висновку, що, говорячи про веб-розробку, завжди кращий вибір зберігати дані, пов'язані з файлом, окремо від імені файлу.

Майте на увазі, що нині, коли переважають мобільні інтерфейси, власне ім’я файлу є менш важливою річчю, що це було 5, 10 років тому. Але навіть якщо це буде вирішальним у контексті вашої програми, ви завжди можете задіяти якусь стару шкільну магію із залученням Content-Disposition: attachment; filename="pretty_file_name.jpg"HTTP-заголовка, побудувавши будь-яке відповідне ім’я файлу. Також сучасні браузери прокладають шлях до нового атрибуту HTML5, завантажують . Я не вірю, що насправді бачити ім'я зображення, "читабельне по-людськи" - це те, про що слід думати в більшості випадків.

UPD: Можлива модифікація, щоб не було занадто багато файлів в одному каталозі - просто візьміть перші 3 букви та створіть реж.


1
Невже md5 справді унікальний?
I.devries

@ I.devries, я не фахівець, але, наскільки я знаю, це досить добре для цих цілей. Особливо , якщо ви будете додатково перевірити розмір файлу, так як алгоритм хешування добре на насправді надають , що об'єкти в тому ж розмірі буде менше , ймовірно, зіткнення - stackoverflow.com/questions/2442632 / ...
shabunc

-1

Шанси на зіткнення з чимось на зразок sha4 є нескінченними. Якщо ви поєднуєте хеш з userid або навіть простою датою, тим більше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.