Javascript - Як витягти ім'я файлу з елемента керування введенням файлу


117

Коли користувач вибирає файл на веб-сторінці, я хочу мати змогу витягнути лише ім’я файлу.

Я спробував функцію str.search, але, здається, не вдалося, коли ім'я файлу виглядає приблизно так: c: \ uploads \ ilike.this.file.jpg .

Як ми можемо витягти лише ім’я файлу без розширення?

Відповіді:


127

Якщо припустити, що ваш <input type = "file"> має ідентифікатор завантаження, це, сподіваємось, виконає трюк:

var fullPath = document.getElementById('upload').value;
if (fullPath) {
    var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
    var filename = fullPath.substring(startIndex);
    if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
        filename = filename.substring(1);
    }
    alert(filename);
}

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

Я додав ці два рядки коду, щоб витягти лише ім'я файлу без розширення: "filename = filename.substring (0, filename.length-4); filename = filename.toLowerCase ();"
Йогі Ян 007

13
Ні, ви не хочете робити це так, як каже Йогі Ян. Замість цього використовуйте: filename = filename.substring(0, filename.lastIndexOf('.'));Тому що його шлях провалиться з розширенням більше символів, ніж 3, таким чином: .html, .jpeg тощо
Yeti

1
як отримати імена файлів у разі вибору декількох файлів?
avngr

Чому б не просто так обчислити startIndex? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge

196

Щоб розділити рядок ({filepath} / {filename}) і отримати ім'я файлу, ви можете використовувати щось подібне:

str.split(/(\\|\/)/g).pop()

"Поп-метод видаляє останній елемент з масиву і повертає це значення абоненту."
Мережа розробників Mozilla

Приклад:

від: "/home/user/file.txt".split(/(\\|\/)/g).pop()

Ви отримуєте: "file.txt"


5
Ви також можете це зробити просто за допомогою регексів та без жодної операції з масивом:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
vog

1
відповідь vog насправді близька до 100% точної відповіді на питання (за винятком необхідності зняти розширення.) Ім'я файлу не відрізняється від будь-якого іншого рядка.
Джон Ватт

1
Розщеплений вираз можна скоротити до [\\/]. Крім того, його також попросили зняти розширення файлу. Для повного вирішення, см: stackoverflow.com/a/32156800/19163
ВОГ

багатоплатформна, лаконічна. Чудово.
Марк

Чудове рішення, я не розумію, як це працює, і саме тому подобається більше!
Chatoxz

92

На сьогодні існує набагато простіший спосіб:

var fileInput = document.getElementById('upload');   
var filename = fileInput.files[0].name;

5
Перевірте, fileInput.files.lengthперш ніж дзвонити .name, на випадок, якщо користувач натиснув скасувати.
marcovtwout

29

Дуже просто

let file = $("#fileupload")[0].files[0]; 
file.name

Якщо ви використовуєте TypeScript, тоді його $ ("# fileupload") [0] ["файли"] [0];
Morvael

18

Припустимо:

<input type="file" name="file1" id="theFile">

JavaScript буде:

var fileName = document.getElementById('theFile').files[0].name;

8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];

Це передбачає, що користувач працює під управлінням Windows. Інші операційні системи використовують різні сепаратори траєкторії файлів.
Квентін

Чи потрібно вам перевірити наявність символу '/' також для користувачів, які не є Windows, наприклад, якщо (! Штук) {str.split ('/'); }? Хороше просте рішення, хоча +1
Іван Окслі

IIRC, IE - єдиний браузер, який так чи інакше дає повний шлях до файлу ... Вам не потрібно буде розділятись на інші браузери, такі як Firefox, тому він все ще працює. Хоча я зізнаюся, я не пробував ВСІЙ браузер linux / unix.
ТМ.

6
str.split (/ (\\ | \ /) / г); для windows та * nix
Tracker1

@TM. Chrome використовує підроблену змінну шляху для безпеки, яка є некрасивою; iirc - це різне залежно від того, на якій ОС ви перебуваєте.
lededje

5

Я припускаю, що ви хочете зняти всі розширення, тобто /tmp/test/somefile.tar.gzдо somefile.

Прямий підхід з регулярним виразом:

var filename = filepath.match(/^.*?([^\\/.]*)[^\\/]*$/)[1];

Альтернативний підхід з операцією регулярного вираження та масиву

var filename = filepath.split(/[\\/]/g).pop().split('.')[0];

1
Це не знімає розширення, як цього вимагали.
Джон Ватт

Виправлено. Дякую за підказку!
vog

4

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

<html>
<body>
<script type="text/javascript">
// Useful function to separate path name and extension from full path string
function pathToFile(str)
{
    var nOffset = Math.max(0, Math.max(str.lastIndexOf('\\'), str.lastIndexOf('/')));
    var eOffset = str.lastIndexOf('.');
    if(eOffset < 0 && eOffset < nOffset)
    {
        eOffset = str.length;
    }
    return {isDirectory: eOffset === str.length, // Optionally: && nOffset+1 === str.length if trailing slash means dir, and otherwise always file
            path: str.substring(0, nOffset),
            name: str.substring(nOffset > 0 ? nOffset + 1 : nOffset, eOffset),
            extension: str.substring(eOffset > 0 ? eOffset + 1 : eOffset, str.length)};
}

// Testing the function
var testcases = [
    "C:\\blabla\\blaeobuaeu\\testcase1.jpeg",
    "/tmp/blabla/testcase2.png",
    "testcase3.htm",
    "C:\\Testcase4", "/dir.with.dots/fileWithoutDots",
    "/dir.with.dots/another.dir/"
];
for(var i=0;i<testcases.length;i++)
{
    var file = pathToFile(testcases[i]);
    document.write("- " + (file.isDirectory ? "Directory" : "File") + " with name '" + file.name + "' has extension: '" + file.extension + "' is in directory: '" + file.path + "'<br />");
}
</script>
</body>
</html>

Виведе наступне:

  • Файл з назвою 'testcase1' має розширення: 'jpeg' знаходиться в каталозі: 'C: \ blabla \ blaeobuaeu'
  • Файл із назвою 'testcase2' має розширення: 'png' знаходиться в каталозі: '/ tmp / blabla'
  • Файл із назвою 'testcase3' має розширення: 'htm' знаходиться в каталозі: ''
  • Каталог з назвою 'Testcase4' має розширення: '' знаходиться в каталозі: 'C:'
  • Каталог з назвою 'fileWithoutDots' має розширення: '' знаходиться в каталозі: '/dir.with.dots'
  • Каталог з іменем '' має розширення: '' знаходиться в каталозі: '/dir.with.dots/another.dir'

З && nOffset+1 === str.lengthдодані в isDirectory:

  • Файл з назвою 'testcase1' має розширення: 'jpeg' знаходиться в каталозі: 'C: \ blabla \ blaeobuaeu'
  • Файл із назвою 'testcase2' має розширення: 'png' знаходиться в каталозі: '/ tmp / blabla'
  • Файл із назвою 'testcase3' має розширення: 'htm' знаходиться в каталозі: ''
  • Каталог з назвою 'Testcase4' має розширення: '' знаходиться в каталозі: 'C:'
  • Каталог з назвою 'fileWithoutDots' має розширення: '' знаходиться в каталозі: '/dir.with.dots'
  • Каталог з іменем '' має розширення: '' знаходиться в каталозі: '/dir.with.dots/another.dir'

Зважаючи на тести, ви можете бачити, що ця функція працює досить надійно порівняно з іншими запропонованими тут методами.

Примітка для новачків про \\: \ символ втечі, наприклад \ n означає новий рядок та \ ta вкладку. Щоб дозволити писати \ n, потрібно фактично набрати \\ n.


1
Слідкуйте за цим шляхом: dir.with.dots / fileWithoutDots, оскільки ви отримаєте eOffset менше nOffset і заплутаєте вирази вилучення.
Джессі Чісгольм

Так, виправлено. Тепер це теж має працювати належним чином (додано && eOffset < nOffset).
Єті

2

Вхід : C:\path\Filename.ext
Вихід :Filename

У HTML-коді встановіть onChangeзначення Файлу таким чином ...

<input type="file" name="formdata" id="formdata" onchange="setfilename(this.value)"/>

Якщо ваш ідентифікатор текстового поля є "wpName" ...

<input type="text" name="wpName" id="wpName">

JavaScript

<script>
  function setfilename(val)
  {
    filename = val.split('\\').pop().split('/').pop();
    filename = filename.substring(0, filename.lastIndexOf('.'));
    document.getElementById('wpName').value = filename;
  }
</script>

1

Жоден із висококваліфікованих відповідей насправді не дає "лише ім'я файлу без розширення", а інші рішення є занадто великим кодом для такої простої роботи.

Я думаю, що це повинно бути однолінійним для будь-якого програміста JavaScript. Це дуже простий регулярний вираз:

function basename(prevname) {
    return prevname.replace(/^(.*[/\\])?/, '').replace(/(\.[^.]*)$/, '');
}

Спочатку зніміть що-небудь до останньої косої риси, якщо така є.

Потім зніміть що-небудь після останнього періоду, якщо він присутній.

Це просто, він надійний, він реалізує саме те, що просять. Я щось пропускаю?


1
"дуже простий регулярний вираз" ... Ну, насправді це два регулярні вирази. :-) Дивіться мою відповідь на одноразове рішення.
vog

Так, є також очевидне переписання, щоб упакувати ці два регулярні вирази в один регулярний вираз за допомогою оператора pipe (|). Я думаю, що написаний код зрозуміліший, але він проходить через рядок двічі, що буде проблемою, якщо рядок, як правило, досить довгий. (Шляхи до файлів зазвичай не є, але можуть бути.)
Джон Ватт

1
Мені просто пришпилювали. Будь ласка, не сприймайте це серйозно. Не потрібно оптимізувати, всі запропоновані рішення більш ніж досить швидкі. Дуже довгі шляхи до файлів - це все-таки кілобайти, а не гігабайти. І ця функція буде запущена один раз при завантаженні файлу, а не 1000x у партії. Тут важливі лише правильність та чіткість коду.
vog

1
// HTML
<input type="file" onchange="getFileName(this)">

// JS
function getFileName(input) {
    console.log(input.files[0].name) // With extension
    console.log(input.files[0].name.replace(/\.[^/.]+$/, '')) // Without extension
}

Як видалити розширення


1
Тут пропущена важлива частина питання, "витягнути лише ім'я файлу без розширення". Це допомагає спочатку уважно прочитати питання, перш ніж стрибати, щоб відповісти на нього.
zeh

1
var path = document.getElementById('upload').value;//take path
var tokens= path.split('\\');//split path
var filename = tokens[tokens.length-1];//take file name

0

Жоден з вищезазначених відповідей не працював для мене, ось моє рішення, яке оновлює відключений вхід з ім'ям файлу:

<script type="text/javascript"> 
  document.getElementById('img_name').onchange = function () {
  var filePath = this.value;
    if (filePath) {
      var fileName = filePath.replace(/^.*?([^\\\/]*)$/, '$1');
      document.getElementById('img_name_input').value = fileName;
    }
  };
</script>

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