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


<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.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.sizeFile.type作为性能增强器。

最新更新