<input id='f' name='f' multiple />
我允许用户选择多个文件(来自不同的文件夹(进行上传。我按照此处所述构建所选文件的列表。基本上,所选文件的列表在INPUT
控件之外进行维护,并在提交时填充回f.files
。
所选文件的列表是在用户每次选择文件时从数组中的File
对象f.files
构建的。
到目前为止,这运行良好,除了我无法检测到所选的重复文件。f.files
仅包含文件名,不包含完整路径。
我在File
对象上应用了URL.createObjectURL
,但每次都是不同的 url,即使使用相同的文件也是如此。
(在 Chrome 中,如果连续选择了同一个文件,上传控件将不会触发change
事件。但这对我来说还不够,因为用户可以选择文件 A,然后选择文件 B,然后再次选择文件 A。
如何识别File
对象中的重复文件?
您可以使用FileReader.readAsDataURL()
读取每个文件的内容。
然后,您可以比较文件内容以及每个文件的其他属性,包括File.lastModified
、File.name
、File.size
和File.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.lastModified
、File.name
、File.size
和File.type
作为性能增强器。