winfile

command module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2026 License: MIT Imports: 16 Imported by: 0

README

winfile

winfile is a Windows port of the classic Unix file command. It identifies the type of one or more files by examining their content (magic bytes, encoding heuristics, and structural markers) rather than relying on file extensions alone. Output is compatible with GNU file so it drops into existing scripts and pipelines unchanged.

winfile [OPTION...] FILE...

Installation

Pre-built binary — grab the one for your platform from the Releases page and put it on your PATH. The binaries are self-contained, with nothing to extract or install.

Asset Platform
winfile_windows_amd64.exe Windows, x86-64
winfile_windows_arm64.exe Windows, ARM64
winfile_linux_amd64 Linux, x86-64
winfile_linux_arm64 Linux, ARM64

Rename it to winfile.exe (or winfile) once it is on your PATH: the binary takes its name from argv[0], so whatever you call it is what appears in its messages. On Linux, chmod +x it first.

From source (requires Go 1.21+):

go install github.com/fermat-tech/winfile@latest

Build locally:

git clone https://github.com/fermat-tech/winfile
cd winfile
go build -o winfile.exe .

Usage

winfile [OPTION...] FILE...
Option Long form Description
-b --brief Omit filename prefix
-i --mime Output MIME type string (e.g. image/png; charset=binary)
--mime-type Output MIME type only
--mime-encoding Output charset / encoding only
--extension Output slash-separated list of valid extensions
-f FILE --files-from FILE Read filenames from FILE (one per line)
-F SEP --separator SEP Use SEP instead of : between filename and result
-L --dereference Follow symbolic links
-n --no-buffer Flush output after each file
-N --no-pad Don't pad filenames to a common width
-0 --print0 NUL-terminate output records (for xargs -0)
-p --preserve-date Preserve file access time
-r --raw Don't translate unprintable characters
-s --special-files Treat special files as ordinary
-z --uncompress Look inside compressed files
-Z --uncompress-noreport Like -z but omit the compression type
-k --keep-going Don't stop at first match (always done)
-e TEST --exclude TEST Exclude a test by name (accepted, no-op)
-v --version Print version and exit
Examples
# Basic identification
winfile photo.jpg report.pdf archive.zip

# MIME types for HTTP content-type scripting
winfile --mime-type *.dll

# Inspect compressed files
winfile -z logs.gz

# Pipe-friendly NUL termination
winfile -0 -b *.exe | xargs -0 -I{} echo "Found: {}"

# Feed a list of paths from another tool
Get-ChildItem -Recurse -Filter *.bin | % FullName | winfile -f -

# Brief + separator for custom formatting
winfile -b -F " => " main.go go.mod

# Encoding detection
winfile --mime-encoding *.txt *.json
Sample output
winfile.exe:   PE32+ executable (x86-64), for MS Windows
report.pdf:    PDF document, version 1.7
photo.jpg:     JPEG image data, Exif standard
archive.zip:   Zip archive data
notes.txt:     UTF-8 Unicode text with CRLF line terminators
empty.dat:     empty
script.py:     Python script text executable
main.go:       Go source text
ntdll.dll:     PE32+ DLL (x86-64), for MS Windows

Detected formats

Binary / structured
Category Formats
Executables PE (EXE/DLL/OBJ), ELF, Mach-O
Archives ZIP, gzip, bzip2, XZ, zstd, LZ4, lzip, LZMA, 7-Zip, RAR, tar (ustar/GNU), Cabinet, ar
Office (OOXML) DOCX, XLSX, PPTX (detected inside ZIP)
Office (legacy) OLE2 compound document (DOC, XLS, PPT, MSG)
Images PNG, JPEG, GIF, BMP, TIFF, WebP, AVIF, HEIF/HEIC, ICO, CUR, JPEG 2000, PSD, XCF, PPM/PGM/PBM, SVG
Audio WAV, FLAC, Ogg (Vorbis/Opus/Theora/Speex), MP3, MIDI, AIFF, AU, APE, WavPack
Video AVI, MP4/M4V/MOV/3GP, MKV, WebM, FLV, ASF/WMV, MPEG, H.264
Documents PDF, PostScript, RTF
Fonts TTF, OTF, WOFF, WOFF2
Databases SQLite 3, Microsoft Access
Disk images ISO 9660, MBR boot sector, VMDK, VHD, VHDX, QCOW2
Bytecode Java .class, Python .pyc
Crypto PEM, DER (X.509)
Containers EPUB, JAR, APK (detected inside ZIP)
Text / source code

Encoding detection: UTF-32 (LE/BE BOM), UTF-16 (LE/BE BOM), UTF-8 (with or without BOM), ASCII. CRLF vs LF line endings are reported.

Source languages detected: Go, Python, JavaScript, TypeScript, JSX/TSX, Java, C, C++, C#, Rust, Ruby, PHP, Perl, Shell (bash/sh/zsh/fish), PowerShell, DOS Batch, Lua, R, Swift, Kotlin, Scala, Haskell, OCaml, Elixir, Erlang, Clojure, Lisp, Zig, Nim, V, D, Fortran.

Markup & data: HTML, XML, SVG, CSS/SCSS, JSON, JSON Lines, YAML, TOML, Markdown, reStructuredText, LaTeX, CSV, TSV, SQL, Protocol Buffers, GraphQL.

Build & tooling: Makefile, CMake, Dockerfile, .gitignore.

Shebang detection: identifies the interpreter from #! lines for scripts with no extension.

Windows-specific notes

The following GNU file options have no Windows equivalent and are not supported:

Option Reason
-m FILE / --magic-file winfile uses compiled-in signatures, not libmagic's database format
-c / --checking-printout no magic file to syntax-check
-l / --list no magic strength table
Block/character device types Windows has no /dev device tree

Everything else — MIME output, compression unwrapping, symlink following, padding, NUL termination, files-from, separator, preserve-date — works exactly as on Linux.

Part of the win* toolkit

winfile is one of several GNU/Unix tool ports for Windows maintained under github.com/fermat-tech:

Tool Equivalent
winegrep egrep
winfind find
winls ls
winwc wc
winwhich which
winless less
winheadtail head / tail
windate date
winsort sort
winfile file

License

MIT — see LICENSE.

Documentation

Overview

detect.go is the top-level file analyser for winfile.

[analyseFile] is the entry point: it stats the path, handles Windows special files (symlinks, directories, named pipes, sockets), opens the file, reads the magic-byte window, and delegates to [doAnalyse].

[doAnalyse] runs the two-pass detection pipeline:

  1. Magic-byte scan via [detectMagic] (magic.go).
  2. Text-encoding scan via [detectText] (text.go) if magic returns nil.

If neither pass succeeds the file is reported as "data" with MIME type application/octet-stream.

Compression unwrapping (-z / -Z flags)

When [options.uncompress] is set and the outer format is gzip or bzip2, [decompressFirst] streams the first magicBufSize bytes of the inner payload and runs the two-pass detection on that buffer. The outer compression type is appended to the description unless [options.uncompressNoreport] is set. XZ is identified at the outer level but inner unwrapping is not supported (no XZ decoder in the Go standard library).

Text refinement

[refineText] narrows a generic ASCII/UTF-8 result to a specific language or format using two signals: JSON structural heuristic first, then the file extension as a secondary hint. The extension table covers ~60 languages and markup formats. A separate base-name table handles extension-less files such as Makefile and Dockerfile.

Access-time preservation (-p flag)

When [options.preserveDate] is set, a deferred os.Chtimes call restores the modification time after the file is read. (Windows does not expose the atime separately via Go's os.Lstat, so mtime is used as the best available approximation.)

magic.go implements magic-byte file-type detection.

[detectMagic] reads up to 512+256 bytes from the start of a file and matches them against a table of well-known binary signatures ("magic numbers"). Each entry maps a byte pattern at a fixed offset to a human- readable description, a MIME type string, and a canonical extension.

Format families covered: executables (PE, ELF, Mach-O), archives and compression (ZIP/OOXML, gzip, bzip2, XZ, zstd, LZ4, 7-Zip, RAR, tar, Cabinet), images (PNG, JPEG, GIF, BMP, TIFF, WebP, AVIF/HEIF, ICO, PSD, PPM/PGM/PBM), audio (WAV, FLAC, Ogg/Vorbis/Opus, MP3, MIDI, AIFF), video (AVI, MP4/MOV/M4V, MKV/WebM, FLV, ASF, MPEG), documents (PDF, PostScript, OLE2, RTF), databases (SQLite, Access), bytecode (Java .class, Python .pyc), fonts (TTF, OTF, WOFF, WOFF2), disk images (ISO 9660, MBR, VMDK, VHD/VHDX, QCOW2), and cryptographic containers (PEM, DER).

Format-specific sub-detectors (peDetail, elfDetail, zipDetail, …) inspect additional header fields to produce richer descriptions—e.g. PE files report CPU architecture and EXE-vs-DLL, ZIP containers report OOXML sub-type (DOCX/XLSX/PPTX/JAR/EPUB), and Ogg streams report codec (Vorbis/Opus/Theora/Speex).

winfile is a Windows port of the classic Unix `file` command.

It identifies the type of one or more files by examining their content (magic bytes, encoding heuristics, and structural markers) rather than relying on file extensions alone. Output is compatible with the GNU file command so it can be used as a drop-in replacement in scripts and pipelines on Windows.

Usage:

winfile [OPTION...] FILE...

Common options:

-b              brief output (no filename prefix)
-i              output MIME type string (e.g. image/png; charset=binary)
--mime-type     output MIME type only
--mime-encoding output charset / encoding only
--extension     output slash-separated list of valid extensions
-f FILE         read filenames from FILE (one per line)
-L              follow symbolic links
-z              look inside compressed files (gzip, bzip2)
-Z              like -z but omit the compression wrapper from the description
-0              NUL-terminate output records (for use with xargs -0)

See [usage] for the full option list.

Detection coverage

Binary formats: PE (EXE/DLL), ELF, Mach-O, ZIP and OOXML derivatives (DOCX/XLSX/PPTX/JAR/APK/EPUB), gzip, bzip2, XZ, zstd, LZ4, 7-Zip, RAR, tar (POSIX ustar), PNG, JPEG, GIF, BMP, TIFF, WebP, AVIF/HEIF, ICO, PDF, PostScript, OLE2 (legacy Office), SQLite, Java .class, MKV/WebM, MP4/MOV, AVI, FLAC, Ogg (Vorbis/Opus/Theora), WAV, MIDI, TTF/OTF/WOFF/WOFF2, PEM certificates, and many more.

Text formats: ASCII, UTF-8, UTF-16 LE/BE (BOM-detected), UTF-32 LE/BE; Go, Python, JavaScript/TypeScript, JSX/TSX, Java, C/C++, C#, Rust, Ruby, PHP, Perl, Shell, PowerShell, Batch, Lua, HTML, XML, SVG, CSS/SCSS, JSON, YAML, TOML, Markdown, SQL, Dockerfile, Makefile, and more—detected by content first, extension as a secondary hint.

text.go implements text-file encoding detection.

[detectText] scans a byte sample and attempts to classify it as human- readable text, returning the character encoding and a short description compatible with GNU file output.

Detection order:

  1. UTF-32 BOM (FF FE 00 00 / 00 00 FE FF)
  2. UTF-16 BOM (FF FE / FE FF)
  3. UTF-8 BOM (EF BB BF)
  4. Heuristic scan over up to 8 KiB: count NUL bytes, non-UTF-8 sequences, and control characters. Files with >1 % NUL or >5 % invalid bytes are classified as binary (nil return). Otherwise the result is ASCII if no high bytes appear, or UTF-8 otherwise.

CRLF line endings are noted separately in the description when found, to match GNU file behaviour on Windows-style text files.

[looksLikeJSON] is a lightweight check used by the text-refinement stage in detect.go to promote plain-text files to the JSON MIME type when the content starts with '{' or '['.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL