99 h1 {
1010 text-align : center;
1111 }
12+
13+ .box {
14+ margin : 20px ;
15+ font-size : 32px ;
16+ }
1217 </ style >
1318</ head >
1419
1520< body >
1621 < h1 > 大文件分片(普通版)</ h1 >
1722 < hr />
18- < input type ="file " id ="file " />
23+ < div class ="box ">
24+ md5:< input type ="file " id ="file " />
25+ < h3 id ="chunks "> </ h3 >
26+ </ div >
27+ < div class ="box ">
28+ spark-md5:< input type ="file " id ="file2 " />
29+ < h3 id ="chunks2 "> </ h3 >
30+ </ div >
1931
2032 < script src ="./md5.js "> </ script >
2133 < script >
@@ -51,7 +63,7 @@ <h1>大文件分片(普通版)</h1>
5163 // fileReader.onprogress = (e) => {
5264 // console.log('切片进度:', e);
5365 // };
54-
66+
5567 // 开始读取指定 Blob 或 File 的内容(读取操作完成时,readyState 属性变为 DONE,并触发 loadend 事件)
5668 fileReader . readAsArrayBuffer ( blob ) ;
5769 } )
@@ -70,6 +82,13 @@ <h1>大文件分片(普通版)</h1>
7082 end,
7183 index,
7284 hash : md5 ( index ) ,
85+ /*
86+ 在前端进行大文件上传时,计算文件的哈希值通常是为了确保文件的完整性和唯一性。
87+ 使用循环时的索引(index)来计算哈希值并不是一个合适的方法,
88+ 因为索引只是一个循环变量,并不能反映文件内容的实际信息。
89+ 在计算哈希值时,应该使用文件内容的实际信息,而不是索引来计算哈希值。
90+ 所以 可以用 spark-md5
91+ */
7392 blob,
7493 } ) ;
7594 } )
@@ -110,11 +129,73 @@ <h1>大文件分片(普通版)</h1>
110129 console . time ( '耗时' ) ;
111130
112131 const chunks = await cutFile ( file ) ;
113- console . timeEnd ( '耗时' ) ;
132+ document . querySelector ( '#chunks' ) . innerText = chunks
114133
115134 console . log ( '分片结果:' , chunks ) ;
116135 }
117136 </ script >
137+
138+ < script src ="./spark-md5.js "> </ script >
139+ < script type ="module ">
140+ // 引入spark-md5库
141+ // import { SparkMD5 } from './spark-md5.js';
142+
143+ function calculateFileHash ( file ) {
144+ return new Promise ( ( resolve , reject ) => {
145+ const spark = new SparkMD5 . ArrayBuffer ( ) ;
146+ const fileReader = new FileReader ( ) ;
147+ /*
148+ SparkMD5 是 MD5 算法的快速 md5 实现。此脚本基于 JKM md5 库,这是最快的算法。这最适合浏览器使用
149+ */
150+ fileReader . onload = ( e ) => {
151+ spark . append ( e . target . result ) ; // Append array buffer
152+ resolve ( spark . end ( ) ) ;
153+ } ;
154+
155+ fileReader . onerror = ( ) => {
156+ reject ( '无法读取文件' ) ;
157+ } ;
158+
159+ fileReader . readAsArrayBuffer ( file ) ;
160+ } ) ;
161+ }
162+
163+ // 定义文件每片的分片大小 5MB
164+ const CHUNK_SIZE2 = 1024 * 1024 * 5 ;
165+
166+ const cutFile2 = async ( file ) => {
167+
168+ // 计算文件总分片数
169+ const chunkCount = Math . ceil ( file . size / CHUNK_SIZE ) ; // 分片向上取整,如:5.5片就要分6片
170+ console . log ( '文件总分片数:' , chunkCount ) ;
171+
172+ console . log ( '\n文件分片中...!🚀如果文件是存储SSD固态硬盘中的话,读取速度会有非常大的提升哦!!\n\n' ) ;
173+
174+ const chunks = [ ] ;
175+ // 获取文件分片每片的信息
176+ for ( let i = 0 ; i < chunkCount ; i ++ ) {
177+ chunks . push ( calculateFileHash ( file , i , CHUNK_SIZE ) )
178+ }
179+ // return chunks;
180+ // 最后用Promise并行创建分片
181+ return await Promise . all ( chunks ) ;
182+
183+ // 通过以上的尝试最后速度效果都差不多, 所以可以尝试用多线程worker的方式来处理。
184+ } ;
185+
186+ // 使用示例
187+ document . querySelector ( '#file2' ) . addEventListener ( 'change' , async ( e ) => {
188+
189+ const file = e . target . files [ 0 ] ;
190+ console . time ( '耗时' ) ;
191+
192+ const chunks = await cutFile2 ( file ) ;
193+ document . querySelector ( '#chunks2' ) . innerText = chunks
194+
195+ console . log ( '分片结果:' , chunks ) ;
196+
197+ } ) ;
198+ </ script >
118199</ body >
119200
120201</ html >
0 commit comments