os.Stat() 能获取文件大小、权限、修改时间等系统级元数据,不能获取EXIF、XMP、PDF/Info等嵌入式格式特定元数据;需用go-exiftool处理GPS、作者、设备型号等字段。

os.Stat() 能拿到什么,不能拿到什么
os.Stat() 是最轻量、最常用的文件元数据入口,但它只返回操作系统层面的通用信息:大小、权限、修改时间、是否为目录等。它不读取文件内容,所以对 EXIF、XMP、PDF /Info 字典、Office 文档属性这些嵌入式元数据完全无感。
常见误判点:
- 看到
FileInfo.Size()就以为是“文件真实体积”,但对稀疏文件或某些网络文件系统,该值可能失真 - 调用
fi.Mode().IsRegular()返回 false 时,别急着报错——可能是符号链接、设备文件或命名管道,需结合os.Lstat()和fi.Mode() & os.ModeSymlink判断 - Windows 下
FileInfo.Sys()返回的是*syscall.Win32FileAttributeData,想取创建时间必须显式类型断言,且该字段在 FAT32 等旧文件系统上根本不存在
什么时候必须用 go-exiftool,而不是自己解析
当你需要读取 JPEG 的 GPS 坐标、PDF 的作者/标题、DOCX 的最后编辑者、MOV 的拍摄设备型号——这些都属于格式特定的嵌入元数据,os.Stat() 和标准库完全不覆盖。这时 go-exiftool 是更稳妥的选择,因为它复用了 ExifTool 引擎,支持 300+ 文件格式,且能处理标签编码混乱、字段嵌套、二进制 blob 解析等边界情况。
但要注意:
立即学习“go语言免费学习笔记(深入)”;
- 必须提前在系统中安装
exiftool(Debian/Ubuntu:sudo apt-get install exiftool;macOS:brew install exiftool) -
go-exiftool.NewExiftool()启动的是一个长期存活的子进程,不是每次调用都 fork —— 所以务必defer et.Close(),否则会残留僵尸进程 - 默认返回所有字段(含冗余),若只需
DateTimeOriginal和GPSPosition,用et.ExtractMetadataWithArgs("path.jpg", "-DateTimeOriginal", "-GPSPosition", "-j")显式指定,避免解析开销
multipart.FileHeader 只是“表单头”,不是文件真相
HTTP 上传时拿到的 *multipart.FileHeader,本质是浏览器塞进 multipart boundary 里的头部描述,和文件本体无关。它的 FilenName 可被任意篡改,Size 在流式中断时不可信,Header.Get("Content-Type") 多数时候是空或 application/octet-stream。
真正可靠的元数据提取路径是:
- 先用
r.ParseMultipartForm(32 解析(32MB 是较安全的内存上限) - 再用
f, fh, err := r.FormFile("file")拿到io.ReadCloser和*multipart.FileHeader - 从
f读前 512 字节,传给http.DetectContentType()得到真实 MIME 类型 - 若需深度元数据(如图片 EXIF),把这 512 字节 + 剩余内容拼成临时文件,再交给
go-exiftool或pdfcpu处理 - 永远不要直接用
fh.Filename作磁盘路径——先用filepath.Base()截掉路径遍历部分,再加随机前缀防重名
PDF 和 Office 文档要分层处理
PDF 的元数据分两层:一是文件系统层(os.Stat())、二是文档结构层(/Info 字典)。很多 PDF 根本没写 /Info,pdfcpu info 返回空不是 bug,是事实。同理,.docx 是 ZIP 包,其作者、修订时间藏在 [Content_Types].xml 和 docProps/core.xml 里,标准库无法自动解压并定位。
实操建议:
- 对 PDF,先跑
pdfcpu validate -v file.pdf确认结构合法,再用pdfcpu info file.pdf查 /Info;若为空,说明作者/标题字段本就未嵌入 - 对 DOCX/XLSX,用
archive/zip打开,读取docProps/core.xml,用encoding/xml解析dcterms:created、cp:lastModifiedBy等节点 - 避免用
gofpdf读取——它只写不读;也别指望go-exiftool能稳定提取 Office 文档的修订历史,ExifTool 对 OOXML 支持有限,优先走 ZIP+XML 路径
http.Error()。尤其当用户上传损坏的 PDF 时,pdfcpu 可能 panic,需用 recover() 捕获并降级返回基础文件信息。


















