(defun string<-file (file-path)
(with-open-file (in-stream file-path :direction :input)
(let ((input-string (make-string (file-length in-stream))))
(read-sequence input-string in-stream)
input-string)))
This works except that the end of the string contains a copy of some of the
final characters from the file. For example, if I read in a file
containing:
name,age
Tony,40
Fred,30
Mary,50
Sally,10
The resulting string when printed looks like this:
"name,age
Tony,40
Fred,30
Mary,50
Sally,10y,10" <== Note the "y,10" duplicated at the end.
I believe this is happening because I am running this on Windows, which uses
CRLF for newlines. When read into the string the sequence CRLF is being
replaced with a single newline character. This means that the string ends
up being a bit longer than necessary and read-sequence is filling the
remaining space by duplicating some of the characters.
I would be grateful if anyone could indicate a way of overcoming this.
Thankyou.
Tony
Melbourne, Australia
Sounds like you are saying that read-sequence is broken. If so, perhaps
you could work around that problem by repeated use of read-line?
(let* ((input-string (make-string (file-length in-stream)))
(pos (read-sequence input-string in-stream)))
(subseq input-string 0 pos))))
Or read the file line by line with READ-LINE and assemble the results
with WITH-OUTPUT-TO-STRING.
Cheers,
Edi.
--
Lisp is not dead, it just smells funny.
Real email: (replace (subseq "spam...@agharta.de" 5) "edi")
> Sounds like you are saying that read-sequence is broken.
No, it's not broken, it works as described. His analysis is correct,
though, which is due to the fact that FILE-LENGTH reports the number
of octets on most Common Lisp implementations, i.e. it doesn't care
about encodings or line endings.
I have also seen your problem because the file was created with
:overwrite instead of :supersede in CL's OPEN. If the new content
is shorter than the previous you can get garbage on the end using
an :overwrite. But here is a version that should work if you
are right , so....
(defun string<-file (file-path)
(with-open-file (in-stream file-path :direction :input)
(let ((input-string (make-array (file-length in-stream) :element-type 'character
:adjustable t :fill-pointer t)))
(setf (fill-pointer input-string) (read-sequence input-string in-stream))
input-string)))
Wade
Just tested your verson and its working fine.
Thanks very much for your help.
Tony