Thursday, March 11, 2010

Read and print lines from a URL

My goal for the next few days is to understand the clojure programming style, and how to think about it. The Reader page has lots of basic information needed to use clojure effectively. The following code:

1. imports some Java classes,
2. defines a BufferedReader for a URL, and
3. uses the with-open function to read a couple of lines from the reader.
4. tries - and fails! - to write a loop to read the entire stream

It works. Kinda. I still haven't figured out how to detect EOF in the loop. I guess I could look it up, but I wouldn't learn very much that way.
Plus, its not good code yet - it does not have the lispy, functional feel to it at all. Once I have it working, I will request a code review in the clojure group.


; import necessary classes
(import java.net.URL)
(import '(java.io BufferedReader IOException InputStreamReader PushbackReader))

; define a BufferedReader
(def bufferedReader
(new BufferedReader
(new InputStreamReader
(. (new URL "http://www.yahoo.com") openStream)
)
)
)


; read and print 2 lines. 1st line is blank
user=> (with-open [rdr bufferedReader]
(println (.readLine rdr))(println (.readLine rdr)))

nil

; the following does read all the bytes. however it ends up throwing a
; NullPointerException when it tries to get the 1st char of a null value at EOF
; And I don't like the dirty comparison to -1 (Java null character). So lots of
; scope for improvement
; define bufferedReader again before running the following, or we
; get an end of stream error
(with-open [rdr bufferedReader]
(loop [line (.readLine rdr)]
(println line)
(recur
(if (not (= -1 (subs line 0))) (.readLine rdr)
)
)
)
)

; the substring function subs.
; remember the the indexes are always between characters.
; index 0 is before 'h'. index 1 is between 'h' and 'e'
user=> (subs "hello" 2)
"llo"
user=> (subs "hello" 2 3)
"l"
user=> (subs "hello" 1 3)
"el"

; read a line from a file
; works great! only i didn't write it. :) I got it from some web site.
(with-open [rdr (java.io.BufferedReader.(java.io.FileReader. "c:\\python31\\LICENSE.txt"))]
(println (.readLine rdr)))

No comments:

Post a Comment