简体   繁体   English

使用FileReader读取和复制文件数据

[英]Read and copy file data with FileReader

I am trying to read files from a client through FileReader. 我正在尝试通过FileReader从客户端读取文件。 I want to create a copy in the browser but I can't figure out how to do it properly. 我想在浏览器中创建一个副本,但是我不知道如何正确地进行操作。 In this JSFiddle i have replicated my problem with the exception that I use a custom class File instead of Object, but it's the same result. 在这个JSFiddle中 ,我用一个自定义类File而不是Object来复制我的问题,但是结果是相同的。

If I only select one file, everything is perfectly fine,but as soon as I select multiple files the errors appear. 如果我只选择一个文件,那么一切都很好,但是当我选择多个文件时,就会出现错误。 Firstly, all properties of the new Object i create on line 9 except the data is always the last file selected. 首先, line 9创建的新对象的所有属性,除了data始终是最后选择的文件。 The function storeResult get the result from fileReader OK, but not from my new Object file? 函数storeResultstoreResult可以获取结果,但不能从新的Object文件获取结果吗?

When I click 'Check Array' all objects in the arrays property data is now the last file selected. 当我单击“检查数组”时,数组属性data中的所有对象现在是最后选择的文件。 My guess is that it has something to do with scope of some of my variables but I can't figure out where and why. 我的猜测是,这与我的某些变量的范围有关,但我不知道在哪里以及为什么。

You have a mutating reference bug : 您有一个变异的参考错误

var files = evt.target.files, i, f; 
for (i = 0; f = files[i]; i++) {
    var reader = new FileReader()
    reader.onload = function onLoad(event) {
        // f is available here
        // but it is not a fixed reference.
        // It changes each time the body
        // of the loop is executed.
        // This function (regardless of the current value of `i`)
        // will only be executed after the containing `for` loop
        // has run to completion.
    };

    // Schedule some work for later
    reader.readAsDataURL(f);
}

The simplest fix is to store a reference to the current f in a closure: 最简单的解决方法是在闭包中存储对当前f的引用:

reader.onload = (function createHandler(currentFile) {
  return function onLoad(event) {
    // f is available here
    // but it is not a fixed reference.

    // `currentFile` is pointing at the value for `f`
    // as it is for this iteration of the loop
    // (that is, it is a fixed reference).
  };

// In order to preserve the state of `f`
// we create a new reference to the value that `f` points
// to for this new function closure and bind it to `currentFile`
// by passing in `f` to our createHandler Immediately Invoked Function Expression
}(f));

And then it becomes even clearer what we are doing if we refactor out the factory function: 然后,如果我们重构出工厂功能,我们将变得更加清楚:

// As a "top-level" function
function createHandler(currentFile) {
  return function onLoad(event) {
    // f is *not* available here.
    // `currentFile` is a reference to the value of
    // whatever is passed in to our `createHandler` function.
    // (that is, it is a fixed reference).
  };
}

// Then, in our handler:
reader.onload = createHandler(f);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM