# How to use multiple file ports

**URL:** <https://racket.discourse.group/t/how-to-use-multiple-file-ports/3310>\
**Category:** Questions & Answers\
**Created:** [November 11, 2024, 5:37pm UTC](https://racket.discourse.group/t/how-to-use-multiple-file-ports/3310 "2024-11-11T17:37:46Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rvdalen](https://avatars.discourse-cdn.com/v4/letter/r/b4bc9f/32.png) [@rvdalen](https://racket.discourse.group/u/rvdalen)\
**Post date:** [November 11, 2024, 5:37pm UTC](https://racket.discourse.group/t/how-to-use-multiple-file-ports/3310/1 "2024-11-11T17:37:47Z")

</div>

I am trying to open 1 file for reading and another for writing, and ensure that if something goes wrong I always try to close the input and output ports. I thought there would be a compact structure for this but the code I came up with seems quite verbose:

```scheme
(define (write-sections-to-file section-table filepath)
  (let ([out-filepath (string-append filepath ".2")]
        [in-port undefined]
        [out-port undefined])
    (dynamic-wind
      (lambda () #f)
      (lambda ()
        (set! in-port (open-input-file filepath #:mode 'text))
        (set! out-port (open-output-file out-filepath #:mode 'text #:exists 'truncate))
        ; Do some stuff
        )
      (lambda ()
        (when (some? out-port)
          (close-output-port out-port))
        (when (some? in-port)
          (close-input-port in-port))))))

```

Is there a more idiomatic way to write this to get rid of `(set!)` and `(dynamic-wind)`?

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [November 11, 2024, 6:38pm UTC](https://racket.discourse.group/t/how-to-use-multiple-file-ports/3310/2 "2024-11-11T18:38:18Z")

</div>

[`call-with-input-file*`](https://docs.racket-lang.org/reference/file-ports.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._call-with-input-file%2A%29%29) and [`call-with-output-file*`](https://docs.racket-lang.org/reference/file-ports.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._call-with-output-file%2A%29%29) are your friends.

A convenient wrapper that opens two files using them:

```scheme
(define (call-with-input/output-files* infile-name outfile-name proc
                                       #:input-mode [input-mode 'binary]
                                       #:output-mode [output-mode 'binary]
                                       #:exists [exists 'error]
                                       #:permissions [permissions #o666]
                                       #:replace-permissions? [replace-permissions? #f])
  (call-with-input-file* infile-name #:mode input-mode
    (lambda (infile)
      (call-with-output-file* outfile-name #:mode output-mode #:exists exists #:permissions permissions #:replace-permissions? replace-permissions?
                              (lambda (outfile) (proc infile outfile))))))

;;; (call-with-input/output-files* "in.txt" "out.txt"
;;; (lambda (in out) (write-string (read-line in) out)))

```

---

<div class="post-metadata">

**Author:** ![rvdalen](https://avatars.discourse-cdn.com/v4/letter/r/b4bc9f/32.png) [@rvdalen](https://racket.discourse.group/u/rvdalen)\
**Post date:** [November 12, 2024, 5:22am UTC](https://racket.discourse.group/t/how-to-use-multiple-file-ports/3310/3 "2024-11-12T05:22:02Z")

</div>

Thanks @shawnw. I was hoping there is already something like this built into racket or the standard library. I can roll my own but wanted to check if this problem has already been solved and I just don't know about it 🙂
