前端面试题input file之后为什么可以展示图片呢?

input file之后为什么可以展示图片呢?

  • 一般的答案都是说浏览器读取了文件,返回了一个dataType的对象,对象里有个buffer[],这样就可以取出来数据展示了。
  • 更有甚至处理方式是读取之后上传到服务器返回url,然后展示url。
  • 这样的解释未免太不严谨。

我们可以从浏览器的角度来思考

  • 浏览器需要对操作系统发送读取请求,操作系统切换特权级进入文件系统,查找文件,通过内存置换算法把文件加载到物理内存中。
  • 操作系统的浏览器线程所包含的虚拟内存会连接到物理内存,操作系统会把文件的内存地址返回给浏览器。
  • 浏览器拿到了文件的内存地址,通过地址访问内存,拿到数据。这时候数据是个buffer[]或者说我们把内存start到start+file.length之间的内存页帧中 存储着文件的二进制数据加载到了缓冲区中。
  • 但是现在的数据是二进制数据,没办法直接用。需要我们进行针对的处理。
  • 这里参照浏览器平台的实现,创建一个dom对象。使用URL.createObjectURL()来吧buffer[]转换成url(注意处理时,需要指定file type)1
        fileInput.addEventListener('change', (event) => {
            const file = event.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.readAsArrayBuffer(file);
 
                reader.onload = () => {
                    const buffer = reader.result;
                    // 这里可以对 buffer 进行处理
                    console.log('ArrayBuffer:', buffer);
                    // 示例:将 ArrayBuffer 转换为 Uint8Array 并打印前 10 个字节
                    const uint8Array = new Uint8Array(buffer);
                    console.log('First 10 bytes:', uint8Array.slice(0, 10));
                    // 示例:如果是图片文件,可以将其显示出来
                    if (file.type.includes('image')) {
                        const blob = new Blob([buffer], { type: file.type });
                        const url = URL.createObjectURL(blob);
                        const img = document.createElement('img');
                        img.src = url;
                        output.appendChild(img);
                    }
                };
 
                reader.onerror = () => {
                    console.error('Error reading file:', reader.error);
                };
            }
        });
  • 之后修改dom对象的数据属性和插入到dom tree太过简单,这里就不展开了。

为什么要指定file type

  • 有朋友会很自然的说,你不指定,浏览器怎么知道是什么类型。
  • 这话虽然没错,但是计算机中的一切都是人定义的,没有天经地义的东西。
  • 完全可以在设计的时候指定文件u8[]的前十个字节存储文件类型。 为什么不呢?

文件为什么是无状态数据流

展开查看

点击展开答案...

Footnotes

  1. 这里说到底还是浏览器的实现太过粗糙,参照其他软件的设计,我们完全可以直接对u8[]进行处理而不需要转为url

For Paul

这是一个个人博客,主要用于记录自己的学习过程,用于技术交流

© 2025 Paul Blog • Made withby Paul

使用 Next Rust 和 Tailwind CSS 构建

最近更新时间: 2025-07-01