emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: map-file-lines


From: Thierry Volpiatto
Subject: Re: map-file-lines
Date: Tue, 03 Feb 2009 11:45:50 +0100
User-agent: Gnus/5.110011 (No Gnus v0.11) Emacs/23.0.90 (gnu/linux)

Hi Ted!
Ted Zlatanov <address@hidden> writes:

> On Mon, 02 Feb 2009 11:20:07 -0600 Ted Zlatanov <address@hidden> wrote: 
>
> TZ> Emacs Lisp lacks a good way to iterate over all the lines of a file,
> TZ> especially for a large file.  The following code tries to provide a
> TZ> solution, concentrating on reading a block of data in one shot and then
> TZ> processing it line by line.  It may be more efficient to write this in
> TZ> C.  Also, it does not deal with cases where the first line read is
> TZ> bigger than the buffer size, and may have other bugs, but it works for
> TZ> me so I thought I'd post it for comments and criticism.
>
> Updated:
>
> - line count 0-based now, logic is cleaner
> - buffer size 128K by default
> - accept start line and count
> - abort when the lambda func returns nil
> - renamed endline to line-end for clarity
>
> Thanks
> Ted

Can you try `tve-flines-iterator' that work a little like python
iterators work.
I plan to use it in futures versions of traverselisp if it is faster than
actual code (traverselisp don't use this code actually).

,----[ C-h f tve-flines-iterator RET ]
| tve-flines-iterator is a Lisp function in `traverselisp.el'.
| 
| (tve-flines-iterator file &optional nlines startpos bufsize)
| 
| Return an iterator on `nlines' lines of file.
| `startpos' and `bufsize' are the byte options to give to
| `insert-file-contents'.
| 
| [back]
| 
| ===*===*===*===*===*===*===*===*===*===*===
| Example:
| ,----
| | ;; create an elisp-iterator object that
| | ;; record the first 1024 bytes of my .emacs
| | (setq A (tve-flines-iterator "~/.emacs.el" nil 0 1024))
| | 
| | ;; eval as many times as needed or launch it in a loop
| | (tve-next A)
| `----
`----

You can get it with hg here:
hg clone http://freehg.org/u/thiedlecques/traverselisp/

> (defun map-file-lines (file func &optional startline count bufsize)
>   (let ((filepos 0)
>       (linenum 0)
>       (bufsize (or bufsize (* 128 1024))))
>     (with-temp-buffer
>       (while
>         (let*
>             ((inserted (insert-file-contents
>                         file nil
>                         filepos (+ filepos bufsize) 
>                         t))
>              (numlines (count-lines (point-min) (point-max)))
>              (read (nth 1 inserted))
>              (done (< 1 read))
>              result line-end)
>           (dotimes (n (count-lines (point-min) (point-max)))
>               (goto-char (point-min))
>               (setq line-end (line-end-position)
>                     result (if (and startline (< linenum startline))
>                                ()
>                              (if (and 
>                                   count
>                                   (>= (- linenum startline) count))
>                                  (return)
>                                (funcall func 
>                                         (buffer-substring 
>                                          (line-beginning-position)
>                                          line-end)
>                                         linenum)))
>                     done (and done result))
>               (incf filepos line-end)
>               (forward-line)
>               (incf linenum))
>           done)))
>     linenum))
>
> ;;(map-file-lines "/tmp/test" (lambda (line num) (message "%d: %s" num line)))
> ;;(map-file-lines "/tmp/test" (lambda (line num) (message "%d: %s" num line)) 
> 100)
> ;;(map-file-lines "/tmp/test" (lambda (line num) (message "%d: %s" num line)) 
> 100 10)
>

-- 
A + Thierry Volpiatto
Location: Saint-Cyr-Sur-Mer - France





reply via email to

[Prev in Thread] Current Thread [Next in Thread]