Google 网上论坛不再支持新的 Usenet 帖子或订阅项。历史内容仍可供查看。

file to string conversion

已查看 10 次
跳至第一个未读帖子

David Bakhash

未读,
1998年12月22日 03:00:001998/12/22
收件人
hey,

If I wanted to simply read in a file as a string, what's the best way?

dave

Pierre Mai

未读,
1998年12月23日 03:00:001998/12/23
收件人
David Bakhash <ca...@bu.edu> writes:

> If I wanted to simply read in a file as a string, what's the best
> way?

READ-SEQUENCE is probably one of the best ways, if you want to stay
portable. I.e. something along the following lines:

(defun get-file-as-string (filename)
"Returns a string with the content of the file `filename'."
(with-open-file (stream filename)
(read-sequence (make-string (file-length stream)) stream)))

For production-quality code, you should check some of the semantics of
the interaction between ELEMENT-TYPE for OPEN/WITH-OPEN-FILE and
MAKE-STRING (I'm currently not sure, whether the standard guarantees
that ELEMENT-TYPE defaults to a type that's "compatible" with STRING.

You'd also probably not use MAKE-STRING, since MAKE-STRING initializes
it's result, which causes unnecessary cache pollution...

Regs, Pierre

--
Pierre Mai <pm...@acm.org> http://home.pages.de/~trillian/
"One smaller motivation which, in part, stems from altruism is Microsoft-
bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]

Erik Naggum

未读,
1998年12月23日 03:00:001998/12/23
收件人
* Pierre Mai <pm...@acm.org>

| READ-SEQUENCE is probably one of the best ways, if you want to stay
| portable. I.e. something along the following lines:
|
| (defun get-file-as-string (filename)
| "Returns a string with the content of the file `filename'."
| (with-open-file (stream filename)
| (read-sequence (make-string (file-length stream)) stream)))
|
| For production-quality code, you should check some of the semantics of
| the interaction between ELEMENT-TYPE for OPEN/WITH-OPEN-FILE and
| MAKE-STRING (I'm currently not sure, whether the standard guarantees
| that ELEMENT-TYPE defaults to a type that's "compatible" with STRING.

you might also want to check out the return value from READ-SEQUENCE.

| You'd also probably not use MAKE-STRING, since MAKE-STRING initializes
| it's result, which causes unnecessary cache pollution...

well, it would if it did, but MAKE-STRING isn't required to initialize
the allocated vector. in particular, the `initial-element' argument's
default value is implementation-dependent. in Allegro CL 5.0, it is not
initialized. it can be quite an interesting read, actually. (this
taught me to zero out temporary strings used in functions with sensitive
data -- I never thought I'd have to do _that_ in Common Lisp.)

(I have written a SETF'able FILE-CONTENTS function that I use a lot, but
my lawyer is working on the license stuff that should accompany all the
code I want to publish. all the licenses I have seen basically focus on
making it easy to give something away, but very hard to accept it. I
want a license that makes it very easy to accept it in the simplest case
(run it, use it, don't modify it, and don't re-distribute it, tell people
where to find it), with options to get wider licenses (such as giving or
licensing to me modifications of any kind, so the _single_ maintained
version can be improved, and such that those who redistribute are
required to accept all newer versions in addition to or replacing older
versions, etc). if anybody knows of a license that grants something like
this (more details upon request), let me know -- it could save me a _lot_
of lawyer fees. both GNU GPL and LGPL are completely useless. we're
investigating the BSD license.)

#:Erik
--
Nie wieder KrF! Nie wieder KrF! Nie wieder KrF! Nie wieder KrF!

Pierre Mai

未读,
1998年12月23日 03:00:001998/12/23
收件人
Erik Naggum <er...@naggum.no> writes:

> you might also want to check out the return value from READ-SEQUENCE.

Oops, that comes from not posting the code you run through your
listener... Here a more correct version, just for those searching
through DejaNews:

(defun get-file-as-string (filename)
"Returns a string with the content of the file `filename'."
(with-open-file (stream filename)

(let ((result (make-string (file-length stream))))
(read-sequence result stream)
result)))

> | You'd also probably not use MAKE-STRING, since MAKE-STRING initializes
> | it's result, which causes unnecessary cache pollution...
>
> well, it would if it did, but MAKE-STRING isn't required to initialize
> the allocated vector. in particular, the `initial-element' argument's
> default value is implementation-dependent. in Allegro CL 5.0, it is not

My naive reading of MAKE-STRING, when narrowly interpreted, seems to
suggest otherwise: Whereas initial-element's default value is
implementation dependent (i.e. can be anything), it still seems to
require that every element of the string returned is initialized to
this default value (whatever it is)...

OTOH not initialising at all when no inital-element is supplied seems
to me to be the more useful option, but if this was intended, then it
should probably be more clearly stated in the standard...

Well, whatever, it's Christmas, have a nice time, I'll be back next
year ;)

Regs, Pierre.

SLong

未读,
1999年1月22日 03:00:001999/1/22
收件人
David Bakhash wrote:
>
> hey,

>
> If I wanted to simply read in a file as a string, what's the best way?
>
> dave

This defun (or something close to it) will allow you to a file
as a set of newline-delimited strings until it reaches End-Of-File.
When the keyword :return-as-string? allows the lines to be concatenated
into a single string; otherwise a list of the line-strings are
returned.

I did this off the top of my head based on what I remember doing in
an ICAD app weeks ago; it is intended to illustrate con-
cepts more than anything else. Can't guarantee this works. I will try
it in Common Lisp tomorrow and repost as required.

(defun retrieve-file-contents
(pathstring &key (return-as-string? nil))
(labels ((readf (stream line-list)
(let ((result (read-line stream nil 'done)))
(if (not (eql result 'done))
(readf stream (push result line-list)
line-list
)
)
)
(app-str (string list-of-strings)
(if list-of-strings
(app-str
(concatenate
'string
string
(car list-of-strings)
#\newline
)
(cdr list-of-strings)
)
string
)
)
)
(with-open-file (stream-in pathstring :direction :input)
(let ((list-of-strings (reverse (readf stream-in nil))))
(if return-as-string
(app-str "" list-of-strings)
list-of-strings
)
)
)
)
)

0 个新帖子