Javascript - Dosya giriş denetiminden dosya adı nasıl çıkarılır


118

Bir kullanıcı bir web sayfasındaki bir dosyayı seçtiğinde, sadece dosya adını çıkarabilmek istiyorum.

Str.search işlevini denedim, ancak dosya adı şu şekilde olduğunda başarısız görünüyor: c: \ uploads \ ilike.this.file.jpg .

Uzantı olmadan sadece dosya adını nasıl çıkarabiliriz?

Yanıtlar:


128

<İnput type = "file"> dosyanızın bir yükleme kimliğine sahip olduğunu varsayarsak, bunun işe yarayacağını umuyoruz:

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);
}

Teşekkürler, bu iyi çalışıyor gibi görünüyor, ancak sadece uzantısız dosya adı istiyorum. Bunu yukarıdaki kodda nasıl yapabilirim.
Yogi Yang 007

Uzantı olmadan yalnızca dosya adını çıkarmak için bu iki kod satırını ekledim: "dosyaadı = dosyaadı.substring (0, dosyaadı.length-4); dosyaadı = dosyaadı.toLowerCase ();"
Yogi Yang 007

13
Hayır, Yogi Yang'ın söylediği şekilde yapmak istemezsiniz. Bunun yerine şunu kullanın: filename = filename.substring(0, filename.lastIndexOf('.'));Çünkü 3'ten daha fazla karakter içeren uzantılarla onun yöntemi başarısız olacaktır, bu nedenle: .html, .jpeg vb.
Yeti

1
çoklu dosya seçimi durumunda dosya adları nasıl alınır?
avngr

Neden sadece startIndex'i böyle hesaplamıyorsunuz? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge

197

Dizeyi ({dosya yolu} / {dosyaadı}) bölmek ve dosya adını almak için aşağıdaki gibi bir şey kullanabilirsiniz:

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

"Pop yöntemi, dizideki son öğeyi kaldırır ve bu değeri çağırana döndürür."
Mozilla Geliştirici Ağı

Misal:

dan: "/home/user/file.txt".split(/(\\|\/)/g).pop()

alırsın: "file.txt"


5
Bunu sadece normal ifadelerle ve herhangi bir dizi işlemi yapmadan da yapabilirsiniz:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
vog

1
vog'un cevabı, soruya verilen% 100 doğru cevaba gerçekten yakındır (uzantının çıkarılması gerekmesi dışında.) Dosya adı diğer dizelerden farklı değildir.
Jon Watte

1
Bölünmüş normal ifade şeklinde kısaltılabilir [\\/]. Dahası, dosya uzantısının da kaldırılması istendi. Eksiksiz bir çözüm için bkz: stackoverflow.com/a/32156800/19163
vog

çoklu platform, özlü. Harika.
Marc

Harika çözüm, nasıl çalıştığını anlamıyorum ve bu yüzden daha çok beğeniyorum!
Chatoxz

92

Günümüzde çok daha basit bir yol var:

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

5
Kullanıcının iptal seçeneğini tıklaması durumunda fileInput.files.lengtharamadan önce kontrol edin .name.
marcovtwout

29

Çok basit

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

TypeScript kullanıyorsanız, $ ("# fileupload") [0] ["dosyalar"] [0];
Morvael

19

varsayarsak:

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

JavaScript şöyle olacaktır:

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

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

Bu, kullanıcının Windows çalıştırdığını varsayar. Diğer işletim sistemleri farklı dosya yolu ayırıcıları kullanır.
Quentin

Windows olmayan kullanıcılar için de '/' karakterini kontrol etmeniz gerekir mi, örn. İf (! Parçalar) {str.split ('/'); }? Güzel basit çözüm +1
Ian Oxley

IIRC, IE zaten dosyanın tam yolunu veren tek tarayıcıdır ... Firefox gibi diğer tarayıcılarda bölmeniz gerekmeyeceği için hala çalışır. Kabul etsem de HER linux / unix tarayıcısını denemedim.
TM.

6
str.split (/ (\\ | \ /) / g); windows ve * nix için
Tracker1

@TM. Chrome, güvenlik için çirkin olan sahte bir yol değişkeni kullanır; iirc, kullandığınız işletim sistemine bağlı olarak farklılık gösterir.
lededje

5

Sana, yani tüm uzantıları şerit istediğiniz varsayalım /tmp/test/somefile.tar.gziçin somefile.

Regex ile doğrudan yaklaşım:

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

Düzenli ifade ve dizi işlemiyle alternatif yaklaşım:

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

1
Bu, istendiği gibi uzantıyı çıkarmaz.
Jon Watte

Sabit. İpucu için teşekkürler!
vog

4

Bunun kendi versiyonunu yaptım. İşlevim, ondan istediğinizi çıkarmak için kullanılabilir, eğer hepsine ihtiyacınız yoksa, bazı kodları kolayca kaldırabilirsiniz.

<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>

Aşağıdakileri çıktılar:

  • 'Testcase1' adlı dosyanın uzantısı var: 'jpeg' dizinde: 'C: \ blabla \ blaeobuaeu'
  • 'Testcase2' adlı dosyanın uzantısı var: 'png' dizinde: '/ tmp / blabla'
  • 'Testcase3' adlı dosyanın uzantısı: 'htm' şu dizinde: ''
  • 'Testcase4' isimli dizinin uzantısı: '' şu dizinde: 'C:'
  • 'FileWithoutDots' adlı dizinin uzantısı var: '' dizinde: '/dir.with.dots'
  • '' İsimli dizinin uzantısı var: '' dizinde: '/dir.with.dots/another.dir'

Şuna && nOffset+1 === str.lengtheklendi isDirectory:

  • 'Testcase1' adlı dosyanın uzantısı var: 'jpeg' dizinde: 'C: \ blabla \ blaeobuaeu'
  • 'Testcase2' adlı dosyanın uzantısı var: 'png' dizinde: '/ tmp / blabla'
  • 'Testcase3' adlı dosyanın uzantısı: 'htm' şu dizinde: ''
  • 'Testcase4' isimli dizinin uzantısı: '' şu dizinde: 'C:'
  • 'FileWithoutDots' adlı dizinin uzantısı var: '' dizinde: '/dir.with.dots'
  • '' İsimli dizinin uzantısı var: '' dizinde: '/dir.with.dots/another.dir'

Test senaryoları göz önüne alındığında, bu işlevin burada önerilen diğer yöntemlerle karşılaştırıldığında oldukça sağlam çalıştığını görebilirsiniz.

\\: \ ile ilgili yeni başlayanlar için not bir çıkış karakteridir, örneğin \ n yeni satır ve \ ta sekmesi anlamına gelir. Yazmayı mümkün kılmak için \ n, aslında \\ n yazmalısınız.


1
Bu yola dikkat edin: dir.with.dots / fileWithoutDots , nOffset'ten daha az eOffset elde edeceğiniz ve çıkarma ifadelerini karıştıracağınız için.
Jesse Chisholm

Evet, düzelttim. Şimdi bu da düzgün çalışmalı (eklendi && eOffset < nOffset).
Yeti

2

Giriş : C:\path\Filename.ext
Çıkış :Filename

HTML kodunda, Dosya onChangedeğerini şu şekilde ayarlayın ...

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

Metin alanı kimliğinizin 'wpName' olduğunu varsayarsak ...

<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

Yüksek oy alan yanıtların hiçbiri aslında "uzantısız dosya adını" sağlamaz ve diğer çözümler bu kadar basit bir iş için çok fazla koddur.

Bunun herhangi bir JavaScript programcısı için tek satırlık olması gerektiğini düşünüyorum. Bu çok basit bir düzenli ifade:

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

İlk önce, varsa son eğik çizgiye kadar her şeyi soyun.

Ardından, varsa son periyottan sonra her şeyi çıkarın.

Basittir, sağlamdır, tam olarak isteneni uygular. Bir şey mi kaçırıyorum?


1
"çok basit bir normal ifade" ... Aslında bunlar iki normal ifade. :-) Tek regex çözümü için cevabıma bakın.
vog

Evet, bu iki normal ifadeyi dikey çizgi (|) operatörünü kullanarak tek bir normal ifadede paketlemek için bariz bir yeniden yazma da vardır. Kodun yazıldığı şekliyle daha net olduğunu düşünüyorum, ancak dizeyi iki kez çalıştırıyor, eğer dizi genellikle oldukça uzunsa bu bir sorun olur. (Dosya yolları genellikle değildir, ancak olabilir.)
Jon Watte

1
Ben sadece kusuyordum. Lütfen bunu ciddiye almayın. Optimize etmeye gerek yoktur, önerilen tüm çözümler fazlasıyla hızlıdır. Çok uzun dosya yolları gigabayt değil, kilobayttır. Ve bu işlev, toplu olarak 1000x değil, dosya yüklemesi başına bir kez tetiklenecektir. Burada önemli olan tek şey kodun doğruluğu ve açıklığıdır.
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
}

Uzantı nasıl kaldırılır


1
Bu, sorunun önemli bir bölümünü kaçırır, "uzantı olmadan yalnızca dosya adını çıkarın". Cevaplamaya geçmeden önce soruyu dikkatlice okumak yardımcı olur.
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

Yukarıdaki cevaplardan hiçbiri benim için işe yaramadı, işte devre dışı bırakılmış bir girişi dosya adıyla güncelleyen çözümüm:

<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>

-2

JQuery kullanıyorsanız o zaman

$("#fileupload").val();

val () aslında istemediği dosya yolunun tamamını döndürür.
FabricioG
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.