如何从Javascript FileReader中获取文件名?

44
我正在使用JavaScript FileReader在浏览器中加载图像:
e = e.originalEvent;
e.dataTransfer.dropEffect = 'copy';
this.documentFile = e.dataTransfer.files[0];

var reader = new FileReader();
reader.onloadend = function () {
    if (reader.result) {
        console.log(reader);
        $('#theImage').attr('src', reader.result);
    }
};
reader.readAsDataURL(this.documentFile);

代码本身没有问题。我现在想获取图像的原始文件名,但我不知道如何实现,并且在网上查找也没有找到相关信息。

请问有人知道怎样通过FileReader获取文件名吗?欢迎提供任何提示!


我认为FileReader没有名称。你是如何加载文件开始的? - epascarello
@epascarello - 我正在使用文本区域的拖放功能加载文件。然后,我使用Backbone事件获取documentFile。我在原始问题中添加了3行代码以展示我如何做到这一点。这能给你一些想法吗? - kramer65
也许这可以帮到你?https://dev59.com/FGcs5IYBdhLWcg3w1XXZ - Tarmo Saluste
7个回答

61

这可能不是最好的解决方案,但对我来说起作用了。

var reader = new FileReader();
reader.fileName = file.name // file came from a input file element. file = el.files[0];
reader.onload = function(readerEvt) {
    console.log(readerEvt.target.fileName);
};

不是最好的答案,但是可行的。


3
如果你有一个文件数组,这种方法不起作用,我认为最好使用https://dev59.com/FGcs5IYBdhLWcg3w1XXZ上的被接受的答案。 - Dor Cohen
2
正如我所说,这不是最好的答案,但它是可行的。此外,问题并不是关于数组,而是关于获取文件名。我同意,在另一页上的那个答案更适合数组设置。 :) - Phreak Nation

7

我刚刚遇到了同样的问题,这是我解决它的方法:

使用FileReader

 const reader = new FileReader();
 reader.readAsDataURL(event.target.files[0]); // event is from the HTML input
 console.log(event.target.files[0].name);

这在reader.onload或onloaded中是行不通的,因为它们的作用域会丢失event.target。 - OlleMattsson

4
所选答案可行,但我个人更喜欢防止将未知属性分配给现有对象。
我的方法是使用内置的“Map”对象来存储“FileReader”和其“File”之间的连接。这非常好用,因为“Map”允许键是任何东西,甚至是一个对象。
考虑在“window”上进行拖放的此示例,其中可以同时放置多个文件:
// We will store our FileReader to File connections here:
const files = new Map();

window.addEventListener('drop', e => {
    e.preventDefault();

    for (const file of e.dataTransfer.files) {
        const reader = new FileReader();

        files.set(reader, file);

        reader.addEventListener('load', e => {
            // Getting the File from our Map by the FileReader reference:
            const file = files.get(e.target);

            console.log(`The contents of ${file.name}:`);
            console.log(e.target.result);

            // We no longer need our File reference:
            files.delete(e.target);
        });

        reader.readAsText(file);
    }
});

window.addEventListener('dragover', e => {
    e.preventDefault();
});

看,我们成功地完成了操作,而不需要改变我们的FileReader对象!


这是一个不错的解决方案,即使在TypeScript中也是如此,因为在reader对象本身上添加任意属性是不可行的。 - OlleMattsson

1
我通过FileReader这种方式获取了文件名和文件大小。
首先,读取器是一个非常有用的javascript FILE API规范,可以从磁盘上读取文件。
在您的示例中,文件是通过readAsDataURL读取的。
reader.readAsDataURL(this.documentFile);
var name = this.documentFile.name;
var size = this.documentFile.size;

我在我的网站上尝试使用this.files[0],并成功地使用jQuery将名称和大小捕获到输入元素中。
 reader.readAsDataURL(this.files[0]);
 $("#nombre").val(this.files[0].name);
 $("#tamano").val(this.files[0].size);

0
另一种方法是修改FileReader()对象实例,加入自己想要的属性。添加一个类似reader.myOwnFileName的键可以让你在onload回调中访问它。
const reader = new FileReader();

reader.onload = function() {

    console.log("Loaded file '" + reader.myOwnFileName + "' contents: ");
    console.log(reader.result); // output file contents of chosen file.

};

reader.readAsText(this.files[0]); // use readAsText(), readAsDataURL() or other method. 

// make your own key on the object instance:
reader.myOwnFileName = this.files[0].name;

0

我尝试了@Robo Robok的解决方案,但无法在我的Angular应用程序中使其工作。在此启发下,我想出了以下方法,并想知道这是否是正确的方法。我有点怀疑,因为每个上传都有自己的FileReader。

    export class ImageFileUpload {
      imageData: any;
      imageName!: string;
      fileReader!: FileReader;
    }

  selectedFiles!: FileList | null;
  previews: Array<ImageFileUpload> = [];

uploadRenewals(event: any) { // event of html 
    const target = event.target as HTMLInputElement;
    this.selectedFiles = target.files;
   
    if (this.selectedFiles) {
      const numberOfFiles = this.selectedFiles.length;
      for (let i = 0; i < numberOfFiles; i++) {
        const currentSelectedFile = this.selectedFiles[i];

        const newImageFile = new ImageFileUpload();
        newImageFile.imageName = currentSelectedFile.name;
        newImageFile.fileReader = new FileReader();
       
        newImageFile.fileReader.onload = (e: any) => {
          newImageFile.imageData = e.target.result;
        };

        newImageFile.fileReader.readAsDataURL(currentSelectedFile);

        this.previews.push(newImageFile);
      }
    }

  }
}

HTML页面

<input #fileInput (change)="uploadRenewals($event)" multiple type="file">

  <div class="slider">
    <div *ngFor="let preview of previews; let idx = index">
      <img [src]="preview.imageData" [alt]="preview.imageName">
    </div>    
  </div>

-1

如果你想将文件名存储到一个变量中:

var filename;
var reader = new FileReader();
reader.onloadend = function () {
    if (reader.result) {
        console.log(reader);
        $('#theImage').attr('src', reader.result);
        filename = reader.result;
    }
};
reader.readAsDataURL(this.documentFile);

如果你想让它在一个函数中运行:
var reader = new FileReader();
reader.onloadend = function () {
    if (reader.result) {
        console.log(reader);
        $('#theImage').attr('src', reader.result);
        myfunctionafter(reader.result);
    }
};
reader.readAsDataURL(this.documentFile);

如果你想从另一个函数中获取信息:

var reader = new FileReader();
var filename = reader.onloadend = function () {
    if (reader.result) {
        console.log(reader);
        $('#theImage').attr('src', reader.result);
        return reader.result;
    }
};
reader.readAsDataURL(this.documentFile);

当你的reader.onloadend完成时,可能会出现一个问题,它可能在你运行它的函数之前就完成了。那么你应该执行两个函数,并从内部触发myfunctionafter(reader.result)。

或者你可以在之后直接获取src。

var filename = $('#theImage').attr('src');

3
不幸的是,执行alert(reader.result);会返回以下内容:data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgG etc etc.。因此这不是文件名,而是文件的base64编码源。你有什么方法可以获取文件名而不是它的base64编码呢? - kramer65

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接