file - 如何判断文件是否为二进制文件
问题描述
我正在尝试使用以下代码读取文件夹中所有文件的文本:
readALine :: FilePath -> IO ()
readALine fname = do
putStr . show $ "Filename: " ++ fname ++ "; "
fs <- getFileSize fname
if fs > 0 then do
hand <- openFile fname ReadMode
fline <- hGetLine hand
hClose hand
print $ "First line: " <> fline
else return ()
但是,其中一些文件是二进制文件。如何查找给定文件是否为二进制文件?我在https://hoogle.haskell.org/?hoogle=binary%20file中找不到任何此类功能
谢谢你的帮助。
编辑:二进制我的意思是文件有不可打印的字符。我不确定这些文件的正确术语。
我安装了 UTF8-string 并修改了代码:
readALine :: FilePath -> IO ()
readALine fname = do
putStr . show $ "Filename: " ++ fname ++ "; "
fs <- getFileSize fname
if fs > 0 then do
hand <- openFile fname ReadMode
fline <- hGetLine hand
hClose hand
if isUTF8Encoded (unpack fline) then do
print $ "Not binary file."
print $ "First line: " <> fline
else return ()
else return ()
现在它可以工作了,但是在遇到“二进制”可执行文件(称为 esync.x)时,hGetLine hand
表达式出现错误:
"Filename: ./esync.x; "firstline2.hs: ./esync.x: hGetLine: invalid argument (invalid byte sequence)
如何检查文件句柄本身的字符?
解决方案
二进制的定义非常模糊,但假设您的意思是不是有效的 UTF-8 文本的内容。
您应该使用toString
in Data.ByteString.UTF8
which 用替换字符替换非 UTF-8 字符,但不会因错误而失败。
将您的示例转换为使用 UTF-8 ByteStrings:
import Data.Monoid
import System.IO
import System.Directory
import qualified Data.ByteString as B
import qualified Data.ByteString.UTF8 as B
readALine :: FilePath -> IO ()
readALine fname = do
putStr . show $ "Filename: " ++ fname ++ "; "
fs <- getFileSize fname
if fs > 0 then do
hand <- openFile fname ReadMode
fline <- B.hGetLine hand
hClose hand
print $ "First line: " <> B.toString fline
else return ()
此代码不会在二进制文件上失败,但并未真正检测到二进制内容。如果要检测二进制文件,请B.replacement_char
在数据中查找。要检测不可打印的字符,您也可以查找小于 32(空格字符)的代码点。
推荐阅读
- r - R Shiny:如何动态生成反应式表达
- laravel - Query 中的 WhereIn 不适用于数组,有什么解决方案吗?
- python - 如何按块交错两个列表
- php - 如何在某个 Woocommerce 类别存档页面中显示已售出/缺货商品,但不显示在其他商品中?
- c# - 在 LINQ 的右表中左连接最多一行
- javascript - 检查对象的类型
- sql-server - 我们可以在视图或物化视图上设置 CDC 跟踪吗?
- javascript - 如何在 HTML 中查找所有类名的频率
- python-3.x - python3.6 venv找不到正确的路径
- reactjs - React slick how to enable no pause