s c h e m a t i c s : c o o k b o o k

/ Cookbook.FileRandomAccessIO

This Web


WebHome 
WebChanges 
TOC (with recipes)
NewRecipe 
WebTopicList 
WebStatistics 

Other Webs


Chicken
Cookbook
Erlang
Know
Main
Plugins
Sandbox
Scm
TWiki  

Schematics


Schematics Home
Sourceforge Page
SchemeWiki.org
Original Cookbook
RSS

Scheme Links


Schemers.org
Scheme FAQ
R5RS
SRFIs
Scheme Cross Reference
PLT Scheme SISC
Scheme48 SCM
MIT Scheme scsh
JScheme Kawa
Chicken Guile
Bigloo Tiny
Gambit LispMe
GaucheChez

Lambda the Ultimate
TWiki.org

Using Random-Access Input/Output

Problem

You want to read a binary record from somewhere inside a large file of fixed-length records, without reading a record at a time to get there.

Solution

Every file port maintains a file pointer, which is the position within the file from which data is read and to which it is written. Use file-position to get and set the file pointer. file-position takes one or two arguments. When given one argument, that argument is a port and it returns the current position of the file pointer. When given two arguments, the first is a port and the second is a positive integer which specifies the new position for the file pointer in bytes. For example:

;; Write some test data to a file
>(with-output-to-file "test.txt"
   (lambda ()
     (display "Hello there.\nThis is a test.\n")))

;; Open the file we have just written
> (define port (open-input-file "test.txt"))
;; Get the current file position
> (file-position port)
0
;; Read the current line
> (read-line port)
"Hello there."
;; Show the file position has advanced
> (file-position port)
13
;; Skip ahead 4 bytes
> (file-position port (+ 4 (file-position port)))
;; Read the next line to show we have skipped ahead
> (read-line port)
" is a test."
;; Clean up
(close-input-port port)

So if you know records are 5 bytes in length, and you want the 5th record, you would set the file pointer to be 5*5 = 25 and read from there.

Discussion

Only string and file ports are guaranteed to support file-position. Changing the file pointer with file-position always clears the buffer for an input port, and flushes the buffer for an output port. Although ports opened with open-input-output-file share the same file pointer setting the position via one port does not flush the other's buffer.

Setting the file pointer past the end of a file causes the file to be enlarged and filled with #\nul up to the required size.

For some applications peeking, which reads without advancing the file pointer, may be preferrable. The main peeking functions are peek-string and peek-bytes.


Comments about this recipe

Contributors

-- GordonWeakliem - 13 Aug 2004

-- NoelWelsh - 01 Oct 2005

CookbookForm
TopicType: Recipe
ParentTopic: FileRecipes
TopicOrder: 999

 
 
Copyright © 2004 by the contributing authors. All material on the Schematics Cookbook web site is the property of the contributing authors.
The copyright for certain compilations of material taken from this website is held by the SchematicsEditorsGroup - see ContributorAgreement & LGPL.
Other than such compilations, this material can be redistributed and/or modified under the terms of the GNU Lesser General Public License (LGPL), version 2.1, as published by the Free Software Foundation.
Ideas, requests, problems regarding Schematics Cookbook? Send feedback.
/ You are Main.guest