在Windows中获取文件的编码

317

这不是一个编程问题。是否有命令行或Windows工具(Windows 7)可以获取文本文件的当前编码?我肯定可以写一个小的C#应用程序,但我想知道是否已经内置了一些工具?


1
您可以使用一个名为编码识别器(需要Java)的免费工具。您可以在http://mindprod.com/products2.html#ENCODINGRECOGNISER找到它。 - Ville
24
“猜测Windows文件的编码”是标题应该具备的内容。如果您事先不知道,那么您永远无法确定正确的编码。 - Tom Blodget
2
@TomBlodget 你的评论很有道理。那么下面的答案是怎么工作的?他们只是在猜测吗? - starriet
15个回答

322
使用随附于Windows 7的普通老式vanilla Notepad打开您的文件。 当您点击“另存为...”时,它会显示文件的编码。 它看起来像这样: enter image description here 无论默认选择的编码是什么,那就是文件的当前编码。 如果是UTF-8,您可以将其更改为ANSI并点击保存以更改编码(反之亦然)。
有许多不同类型的编码,但当我们的导出文件为UTF-8且第三方要求ANSI时,这就是我所需要的。这是一次性的导出,所以Notepad对我来说很合适。
顺便说一下:据我了解,Notepad中列出的“Unicode”实际上是UTF-16的错误称呼。 关于Notepad的“Unicode”选项,请参阅此处:Windows 7 - UTF-8 and Unicode

更新(06/14/2023):

附有新版记事本和Notepad++的截图。

记事本(Windows 10和11):
   右下角:enter image description here

   "另存为..."对话框:enter image description here

Notepad++: 右下角: enter image description here "编码" 菜单项: enter image description here NotePad++ 提供了更多的编码选项,如果您需要的话。
其他(Mac/Linux/Win)选项:
我听说Windows 11改进了打开100+MB大文件的性能,速度更快。
在网上我读到Notepad++仍然是全能的大文件编辑器冠军。
然而,(对于那些使用Mac或Linux的人)这里还有一些其他的竞争者:
1). Sublime Text
2). Visual Studio Code

1
@Alex,我不使用Win-8。通过谷歌搜索,我找到了这个链接:Win-8记事本。我希望你能找到它,因为我向你保证,它仍然存在。 - MikeTeeVee
1
谢谢您的回复,但在Windows 8.1上确实没有名为记事本的应用程序。当您输入“记事本”进行搜索时,会出现“编辑器”。而这个编辑器没有编码下拉菜单,也没有相应的菜单选项。 - Alex
4
这种方法无法处理对于记事本来说过大的文件。而且,这个限制比Notepad++等其他编辑器更容易触发。 我的Windows 8.1系统中有记事本。可以在%windir%\system32\notepad.exe 中查找。 - Fabian Kessler
3
记事本存在于Windows 8和Windows 10中。 - Alan B
11
记事本自 Windows 3 版本起至今的所有 Windows 版本中都已预装。 - Jean-François Larvoire
显示剩余9条评论

117

如果您的Windows机器上有"git"或"Cygwin",请转到文件所在的文件夹并执行以下命令:

file *

这将给您该文件夹中所有文件的编码详细信息。


1
除了您的答案之外,如果您只对特定文件感兴趣,您可以使用grep命令来过滤file *命令的结果。 - ebram khalil
10
不要盲目运行文件命令,回答这个问题的完整命令是 file --mime-encoding,以获取文件的编码。 - smac89
6
2020年的问题不再是Cygwin,而是WSL或WSL2。Cygwin几乎已经被淘汰了。 - Timo
3
2021年,这适用于git-bash(也称“Git for Windows”附带的shell)。它使用MinGW而不是Cygwin。 - user2864740

78

Linux命令行工具“file”可通过GnuWin32在Windows上使用:

http://gnuwin32.sourceforge.net/packages/file.htm

如果您已安装git,则它位于C:\ Program Files \ git \ usr \ bin。

示例:

    C:\Users\SH\Downloads\SquareRoot>file *
    _UpgradeReport_Files;         目录
    Debug;                        目录
    duration.h;                   ASCII C++程序文本,带有CRLF换行符
    ipch;                         目录
    main.cpp;                     ASCII C程序文本,带有CRLF换行符
    Precision.txt;                ASCII文本,带有CRLF换行符
    Release;                      目录
    Speed.txt;                    ASCII文本,带有CRLF换行符
    SquareRoot.sdf;               数据
    SquareRoot.sln;               UTF-8 Unicode(带BOM)文本,带有CRLF换行符
    SquareRoot.sln.docstates.suo; PCX ver. 2.5图像数据
    SquareRoot.suo;               CDF V2文档,损坏:无法读取摘要信息
    SquareRoot.vcproj;            XML文档文本
    SquareRoot.vcxproj;           XML文档文本
    SquareRoot.vcxproj.filters;   XML文档文本
    SquareRoot.vcxproj.user;      XML文档文本
    squarerootmethods.h;          ASCII C程序文本,带有CRLF换行符
    UpgradeLog.XML;               XML文档文本
C:\Users\SH\Downloads\SquareRoot>file --mime-encoding * _UpgradeReport_Files; 二进制 Debug; 二进制 duration.h; us-ascii ipch; 二进制 main.cpp; us-ascii Precision.txt; us-ascii Release; 二进制 Speed.txt; us-ascii SquareRoot.sdf; 二进制 SquareRoot.sln; utf-8 SquareRoot.sln.docstates.suo; 二进制 SquareRoot.suo; CDF V2文档,损坏:无法读取摘要信息二进制
SquareRoot.vcproj;            us-ascii    => SquareRoot.vcproj;            美国标准信息交换码
SquareRoot.vcxproj;           utf-8      => SquareRoot.vcxproj;           通用字符集转换格式
SquareRoot.vcxproj.filters;   utf-8      => SquareRoot.vcxproj.filters;   通用字符集转换格式
SquareRoot.vcxproj.user;      utf-8      => SquareRoot.vcxproj.user;      通用字符集转换格式
squarerootmethods.h;          us-ascii   => squarerootmethods.h;          美国标准信息交换码
UpgradeLog.XML;               us-ascii   => UpgradeLog.XML;               美国标准信息交换码

1
请注意,您可能需要 git 2.x 才能运行它,我使用的是 git 1.9.5 版本。 - jakub.g
对于我的文件,它显示“二进制” :( - barbara.post
1
令人难以置信的是,为了进行基本操作,我们不得不回到命令行,这已经是2017年了,但看起来还可以。 - Todd Partridge
1
就像另一个答案所说的那样,您也可以在cygwin中使用file命令。任何用于Windows的POSIX工具集都应该有file - palswim
如果您已经安装了Windows版的Git,它会包含GIT BASH(bash模拟器),而该模拟器又包含了“file”命令。只需使用它即可正常工作。这也在下一个答案中提到了... - Amir Katz
显示剩余2条评论

32

安装 Git(在 Windows 上需要使用 Git Bash 控制台)。输入:

file --mime-encoding *   

对于当前目录中的所有文件,或者

file --mime-encoding */*   

对所有子目录中的文件进行操作


文档链接:https://linux.die.net/man/1/file - sommmen
1
不错的回答。 然而,file --mime-encoding */* 将会忽略 */*/* 中的所有文件。 因此,如果你想要捕获整个子目录树中的 所有 文件,你还需要运行 file --mime-encoding */*/*,以此类推。 - Henke

26

4
分析多个文件非常有帮助。 - Eric Bonnot
1
即使是非常大的文件,也能立即得到答案(正如人们所期望的那样)。 - Fabian Kessler
1
适用于当前的Windows 10。 - barbara.post
2
无法确定该页面上的exe文件在哪里。链接过时了吗? - Christoph
2
https://github.com/amrali-eg/EncodingChecker 有一个修改过的版本。 - Jarvars
显示剩余4条评论

21

以下是我对如何通过BOM检测Unicode文本编码的看法。由于此方法仅适用于文本文件(特别是Unicode文件),并且在没有BOM的情况下默认为ascii,因此此方法的准确性较低(就像大多数文本编辑器一样,在没有BOM的情况下默认为UTF8以匹配HTTP/web生态系统)。

更新2018年我不再推荐使用这种方法。 我建议使用GIT的file.exe或*nix工具,如@Sybren所推荐,并在后续答案中展示了如何通过PowerShell实现

# from https://gist.github.com/zommarin/1480974
function Get-FileEncoding($Path) {
    $bytes = [byte[]](Get-Content $Path -Encoding byte -ReadCount 4 -TotalCount 4)

    if(!$bytes) { return 'utf8' }

    switch -regex ('{0:x2}{1:x2}{2:x2}{3:x2}' -f $bytes[0],$bytes[1],$bytes[2],$bytes[3]) {
        '^efbbbf'   { return 'utf8' }
        '^2b2f76'   { return 'utf7' }
        '^fffe'     { return 'unicode' }
        '^feff'     { return 'bigendianunicode' }
        '^0000feff' { return 'utf32' }
        default     { return 'ascii' }
    }
}

dir ~\Documents\WindowsPowershell -File | 
    select Name,@{Name='Encoding';Expression={Get-FileEncoding $_.FullName}} | 
    ft -AutoSize

建议:如果dirlsGet-ChildItem仅检查已知的文本文件,并且您只想要从已知工具列表中查找“错误编码”,则这可能会运行得相当不错。(即SQL Management Studio默认为UTF16,这破坏了Windows下的GIT auto-cr-lf,默认情况下使用多年)


在 poshcode 上有许多变体的 Get-FileEncoding。我甚至还从 Python 和 Nodejs 中审查了 punycode,但是这个小版本对我的使用命中了 80/20(更像是 99/1)。如果您托管其他人的文件,我建议您使用 Syben 的答案(https://dev59.com/6nA65IYBdhLWcg3wogOe#34766140)中的 file 命令或另一个生产质量的 Unicode 解码器。 - yzorg
应该补充说明的是,这种方法仅在存在BOM的情况下才有效...而这并不总是成立。 - Yepeekai
@Yepeekai 最后一行是“默认”编码(当没有BOM时)。对于XML、JSON和JavaScript,默认编码为UTF8,但实际情况可能有所不同。 - yzorg
@yzorg:但这是一种愚蠢的做法。你只是在欺骗用户。至少大多数解析器会做出一个有根据的猜测。如果你无法猜测,就抛出一个错误,并告诉他们需要使用 BOM 来使用你的代码(然后去使用其他更聪明的工具,因为已经有很多了)。 - Ed S.
1
@EdS。在答案#2和答案#1的评论中提到,如果您正在寻找“权威”的编码或文件类型,则可以使用来自cygwin或GIT工具的file.exe。我还在回复其他评论中提到了这一点。我遵循这个建议,在稍后的答案(也是我的)https://dev59.com/6nA65IYBdhLWcg3wogOe#46816054中提供了有关如何从powershell使用`file.exe`的提示。您是否希望我在答案正文中包含该限定词? - yzorg
显示剩余3条评论

15

一个简单的解决方案可能是在Firefox中打开文件。

  1. 将文件拖放到Firefox中
  2. 按Ctrl+I打开页面信息

文本编码将出现在“页面信息”窗口中。

enter image description here

注意:如果文件不是txt格式,只需将其重命名为txt并重试。

P.S. 有关更多信息,请参见this文章。


2
看起来“查看页面信息”已经不再存在,根据2021年4月的Firefox 88已悄然删除这些功能。作为解决方法,可以使用CTRL-I(适用于2022年1月的Windows操作系统)。 - Intrastellar Explorer

8

我写了第四个答案(在写作时)。但是最近我在所有的电脑上都安装了git,所以现在我使用@Sybren的解决方案。这里有一个新答案,可以使该解决方案从powershell方便使用(而不必将所有的git/usr/bin放入PATH中,这对我来说太过杂乱无序)。

将以下代码添加到您的profile.ps1文件中:

$global:gitbin = 'C:\Program Files\Git\usr\bin'
Set-Alias file.exe $gitbin\file.exe

并使用方式如下:file.exe --mime-encoding *。在命令中必须包含.exe以使PS别名生效。

但如果您没有自定义PowerShell profile.ps1,建议从我的开始:https://gist.github.com/yzorg/8215221/8e38fd722a3dfc526bbe4668d1f3b08eb7c08be0 并将其保存到~\Documents\WindowsPowerShell。它可以安全地在没有git的计算机上使用,但在未找到git时会发出警告。

命令中的.exe还是我从powershell使用C:\WINDOWS\system32\where.exe和许多其他默认情况下被powershell隐藏的操作系统CLI命令的方法, *耸肩*。


1
或者你可以将file作为文件file.exe的别名,而不是使用file.exe ¯\(ツ) - scrthq
@ferrell_io 简而言之:PS 基于 .NET 平台,.NET 有 File 静态类,而 PS 中常见的 EXE 还存在着许多混淆参数的情况。因此,我使用 .exe 来区分 PS 和 Windows 自带的可执行文件,例如:dir | where Size -lt 10000where.exe git - yzorg
@ferrell_io 我使用 where.exe 来区分它和 PS 中的 where,后者是 Where-Object 的内置别名。例如: where.exe git*ls . | where Size -lt 10000 - yzorg
@ferrell_io 所以我在检测编码的同一脚本中使用相同的模式来处理 file.exe 与 .NET 静态类,例如:[File]::SetCreationTime("readme.md", [DateTime]::Now) - yzorg

4

你可以通过在文件位置打开git bash并运行命令file -i 文件名来简单检查它。

举个例子:

user filesData
$ file -i data.csv
data.csv: text/csv; charset=utf-8

4

下面是一些C代码,用于可靠地检测ASCII、BOM和UTF8编码:https://unicodebook.readthedocs.io/guess_encoding.html

只有ASCII、UTF-8和使用BOM的编码(带BOM的UTF-7、带BOM的UTF-8、UTF-16和UTF-32)有可靠的算法来获取文档的编码。对于所有其他编码,您必须依靠基于统计学的启发式方法。

编辑:

这是从Effective way to find any file's Encoding中转换为PowerShell版本的C#答案。只能使用文件签名(BOM)工作。

# get-encoding.ps1
param([Parameter(ValueFromPipeline=$True)] $filename)    
begin {
  # set .net current directoy                                                                                                   
  [Environment]::CurrentDirectory = (pwd).path
}
process {
  $reader = [System.IO.StreamReader]::new($filename, 
    [System.Text.Encoding]::default,$true)
  $peek = $reader.Peek()
  $encoding = $reader.currentencoding
  $reader.close()
  [pscustomobject]@{Name=split-path $filename -leaf
                BodyName=$encoding.BodyName
                EncodingName=$encoding.EncodingName}
}


.\get-encoding chinese8.txt

Name         BodyName EncodingName
----         -------- ------------
chinese8.txt utf-8    Unicode (UTF-8)


get-childitem -file | .\get-encoding

2
@jeasoft 谢谢。我添加了一个修复程序来设置.NET当前目录。https://dev59.com/w2gu5IYBdhLWcg3wj3r5 - js2010
这对于ASCII,UTF-8,UTF-8,UTF-8 BOM不起作用,但似乎对UTF-16,UTF-16 BE有效... - undefined
@not2qubit 像我说的那样,只能处理带有字节顺序标记(BOM)的文件,包括UTF-8 BOM。 - undefined
有趣,但还不确定那是如何运作的... - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接