2012-02-10 14 views
7

मैं ज़िप संग्रह में मुट्ठी फ़ाइल से पहले पांच बाइट्स लेना चाहता हूं। मैं विसंपीड़न के लिए ज़िप संग्रह पैकेज का उपयोग करें:ज़िप संग्रह से ढीले बाइटस्ट्रिंग को ढेर ओवरफ्लो

import qualified Data.ByteString.Lazy as L 
import Data.Maybe 
import System.Environment (getArgs) 

import Codec.Archive.Zip 

main = do 
    f:_ <- getArgs 
    print . L.take 5 . fromEntry . head . zEntries . toArchive =<< L.readFile f 

इस कोड को छोटे अभिलेखागार के लिए काम करता है, लेकिन मैं लोगों के साथ बड़ा ढेर अतिप्रवाह मिला है। उदाहरण के लिए:

./zip-arch test.zip +RTS -p -hy -M100M 

इस archive के लिए इस heap profile

+0

यही कारण है, कि एक समस्या का कोई संकेत नहीं है। मैं खुद को देख लूंगा। –

+0

@DanielFischer अजीब, लेकिन मुझे यह त्रुटि संदेश मिला है: ढेर थका हुआ; वर्तमान अधिकतम ढेर आकार 104857600 बाइट्स (100 एमबी) है; इसे बढ़ाने के लिए '+ RTS -M 'का उपयोग करें। – tymmym

+0

@tymmym: 'fromEntry' पैकेज "digest" से CRC32 चेकसम का उपयोग करता है। यह zcib.h में crc32 का आह्वान करके crc32 करता है, यह कुछ स्मृति का उपभोग कर सकता है? मुझे यकीन नहीं है। – Nybble

उत्तर

1

मैं जिप-संग्रह लेखक की explanation पढ़ सकते हैं और सिफारिश की मरम्मत करने के लिए तय कर लिया है:

import System.Environment (getArgs) 
import System.IO (hSetBinaryMode) 
import System.Process (StdStream(...), createProcess, proc, close_fds, std_out) 

import qualified Data.ByteString.Lazy as L 

unzipLBS :: FilePath -> IO L.ByteString 
unzipLBS file = do 
    let args = proc "unzip" ["-p", file] 
     args' = args { std_out = CreatePipe, close_fds = True } 

    (_, Just hOut, _, _) <- createProcess args' 
    hSetBinaryMode hOut True 
    L.hGetContents hOut 

main :: IO() 
main = do 
    f:_ <- getArgs 
    print . L.take 5 =<< unzipLBS f 

काम करने के लिए लगता है। मैंने एक नई लाइब्रेरी - zip-conduit के साथ समाप्त कर लिया है। इसकी मुख्य विशेषता आलसी आईओ के बिना लगातार स्मृति उपयोग है। ज़िप में मुट्ठी फ़ाइल से पहले पांच बाइट्स लेने के लिए संग्रह के आप लिख सकते हैं: ढेर प्रोफ़ाइल 130k का एक ढेर उपयोग दिखाता है

import   System.Environment 
import   Data.Conduit 
import qualified Data.Conduit.Binary as CB 

import   Codec.Archive.Zip 

main = do 
    f:_ <- getArgs 
    res <- withArchive f $ do 
       name:_ <- fileNames 
       source <- getSource name 
       runResourceT $ source $$ CB.take 5 
    print res 
1

unzip के लिए बाहर बुला पर विचार देता है। यह सुपर हैकली नहीं है लेकिन यह काम करता है। शायद वहां सभी शत्रुओं को zip-archive जैसे टूटे पुस्तकालयों को ठीक करने या बदलने में अधिक समय व्यतीत करना चाहिए और स्टैक ओवरफ्लो पर कम समय चाहिए।

मानक अस्वीकरण: कोई त्रुटि जांच नहीं है। यह रिसाव हैंडल हो सकता है। आलसी मैं/आलसी है।

$ runghc -Wall unzip.hs ~/Downloads/test.zip 
Chunk ",+\227F\149" Empty 
संबंधित मुद्दे