2009-03-22 21 views
5

Tôi đang viết một chương trình chạy một quy trình phụ bên ngoài tương tác và tôi cần nội dung của đầu ra xử lý để được xuất ra stdout ngay khi nó có sẵn . Tôi đã thử một cái gì đó như thế này:Haskell: Làm thế nào để đường ống nội dung của một tay cầm vào nhau trong thời gian thực

main = do processInfo <- createProcess (proc "ghci" []){std_out = CreatePipe, 
                std_in = CreatePipe } 
     case processInfo of 
      (Just hIn, Just hOut, _, _) -> do mainloop hIn hOut 
              hClose hIn 
              hClose hOut 
     _        -> do error "Unable to start process" 

mainloop :: Handle -> Handle -> IO() 
mainloop inh outh = 
    do ineof <- hIsEOF outh 
     if ineof 
      then return() 
      else do inpStr <- hGetLine outh 
        putStrLn inpStr 
        mainloop inh outh 

Nhưng điều này không làm việc vì nó chỉ nhận dòng đầu ra bởi dòng, vì vậy bất kỳ sản lượng trên tay cầm quá trình sản xuất mà không được chấm dứt bởi một dòng mới không hiển thị . Tôi đã thử điều tương tự với hGetContents nhưng nó tạo ra kết quả tương tự. Tôi đã đọc qua tài liệu của cả System.Process và System.IO và không thực sự tìm thấy bất cứ điều gì kết luận.

Trả lời

4

hSetBuffering là những gì bạn đang tìm kiếm, mặc định (trên Unix ít nhất) là dòng đệm. Sử dụng nó trên stdin trước khi bắt đầu vòng lặp chính

hSetBuffering hIn NoBuffering 

và tùy chọn trên tay cầm đầu ra nếu bạn muốn xem kết quả ngay lập tức ở phía đầu ra. Tuy nhiên, lưu ý rằng việc tắt đệm có thể làm giảm đáng kể hiệu suất.

+0

Cảm ơn bạn, tôi thậm chí không nghĩ đến việc thay đổi chế độ đệm trên stdin/stdout. – drt

+0

Cần lưu ý rằng mặc định trên Windows khác với mặc định trên Linux vì vậy nó đáng để thiết lập kiểu đệm để có được hành vi nhất quán. – porges

2

Tôi là một người mới của Haskell, nhưng tôi nhớ đã xem qua một ví dụ gần đây về xử lý ký tự đầu vào theo ký tự. Có phải hSetBuffering có thể là những gì bạn đang tìm kiếm không?

0

Đệm là một điều, nhưng bạn cũng đang sử dụng gGetLine sẽ đợi toàn bộ dòng (hoặc kết thúc tệp). Cân nhắc sử dụng hGetChar nếu bạn thực sự muốn đọc một ký tự tại thời điểm đó. Và btw, một cách khác để khắc phục bộ đệm là sử dụng hFlush.

Các vấn đề liên quan