如何检测到不同的File对象引用的是同一个文件?

时间:2018-08-30 03:50:22

标签: javascript

<input id='f' name='f' multiple />

我允许用户从多个文件夹中选择多个文件进行上传。如here所述,构建了选定文件的列表。基本上,所选文件的列表在INPUT控件之外进行维护,并在提交时填充回f.files中。

每次用户选择文件时,都会根据数组File中的f.files对象建立所选文件的列表。

到目前为止,除了我无法检测到所选的重复文件之外,此方法运行良好。 f.files仅包含文件名,而不包含完整路径。

我在URL.createObjectURL对象上应用了File,但是每次使用不同的URL时,即使使用相同的文件。

(在Chrome中,如果连续选择了同一文件,则上传控件将不会触发change事件。但这对我来说还不够,因为用户可以选择文件A,然后选择文件B,然后再次提交A。)

如何从File对象中识别重复文件?

1 个答案:

答案 0 :(得分:0)

您可以使用FileReader.readAsDataURL()来读取每个文件的内容。

然后,您可以比较文件内容以及每个文件的其他属性,包括File.lastModifiedFile.nameFile.sizeFile.type,以确定文件是否为副本。

完整示例:

const file_input = document.getElementById( 'f' );

file_input.addEventListener( 'change', () =>
{
    const file_compare = [];
    
    Array.from( file_input.files ).forEach( file =>
    {
        const file_reader = new FileReader();
        
        file_reader.readAsDataURL( file );
        
        file_reader.addEventListener( 'load', () =>
        {
            const file_exists = file_compare.find( existing_file =>
                
                   existing_file.lastModified === file.lastModified
                && existing_file.name         === file.name
                && existing_file.size         === file.size
                && existing_file.type         === file.type
                && existing_file.content      === file_reader.result
                
            ) !== undefined;
            
            if ( file_exists )
            {
                console.log( 'Error:', file.name, 'is a duplicate file.' );
            }
            
            else
            {
                file_compare.push(
                {
                    'lastModified' : file.lastModified,
                    'name'         : file.name,
                    'size'         : file.size,
                    'type'         : file.type,
                    'content'      : file_reader.result
                });
            }
        });
    });
});
<input id="f" name="f" type="file" multiple />

  

注意:如果您要处理的文件非常大,则可以将比较范围限制为File.lastModifiedFile.nameFile.size和{{1} }作为性能增强器。