I am trying to write a hexdump like program in Haskell. I wrote the following program, I am glad that it works and gives desired output but it is very slow and inefficient. It was adapted from the program given in this answer.
I ran the program with a sample file, and it takes about 1 minute to process that less than 1MB file. The standard Linux hexdump program does the job in less about a second. All I want to do in the program is read->process->write all individual bytes in a bytestring.
Here is the question - How to efficiently read/process/write the bytestring (byte by byte, i.e. without using any other functions like getWord32le
, if that's what is needed)? I want to do arithmetical and logical operations on each individual byte not necessarily on the Word32le
or a group of bytes like that. I didn't find any data type like Byte.
Anyway, here is the code I wrote, which runs successfully on ghci (version 7.4) -
module Main where
import Data.Time.Clock
import Data.Char
import qualified Data.ByteString.Lazy as BIN
import Data.ByteString.Lazy.Char8
import Data.Binary.Get
import Data.Binary.Put
import System.IO
import Numeric (showHex, showIntAtBase)
main = do
let infile = "rose_rosebud_flower.jpg"
let outfile = "rose_rosebud_flower.hex"
h_in <- openFile infile ReadMode
System.IO.putStrLn "before time: "
t1 <- getCurrentTime >>= return . utctDayTime
System.IO.putStrLn $ (show t1)
process_file h_in outfile
System.IO.putStrLn "after time: "
t2 <- getCurrentTime >>= return . utctDayTime
System.IO.putStrLn $ (show t2)
hClose h_in
process_file h_in outfile = do
eof <- hIsEOF h_in
if eof
then return ()
else do bin1 <- BIN.hGet h_in 1
let str = (Data.ByteString.Lazy.Char8.unpack) bin1
let hexchar = getHex str
System.IO.appendFile outfile hexchar
process_file h_in outfile
getHex (b:[]) = (tohex $ ord b) ++ " "
getHex _ = "ERR "
tohex d = showHex d ""
When I run it on the ghci I get
*Main> main
before time:
23254.13701s
after time:
23313.381806s
Please provide a modified (but complete working) code as answer and not just the list of names of some functions. Also, don't provide solutions that use jpeg or other image processing libraries as I am not interested in image processing. I used the jpeg image as example non-text file. I just want to process data byte by byte. Also don't provide links to other sites (especially to the documentation (or the lack of it) on the Haskell site). I cannot understand the documentation for bytestring and for many other packages written on the Haskell site, their documentation (which is just type signatures collected on a page, in most cases) seems only meant for the experts, who already understand most of the stuff. If I could figure out the solution by reading their documentation or even the much advertised (real world haskell) RWH book, I'd not have asked this question in the first place.
Sorry for the seeming rant, but the experience with Haskell is frustrating as compared to many other languages, especially when it comes to doing even simple IO as the Haskell IO related documentation with small complete working examples is almost absent.