2019-03-31 11:00:21 +00:00
---
title: ファイルの読み書き
author: kazu634
date: 2011-04-02
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5421;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- gauche
---
< div class = "section" >
< p >
Gaucheでファイルの読み書きをする場合の処理を作成してみました。
< / p >
< h4 >
作成する処理について
< / h4 >
< p >
こんなのをイメージして作ったよ。
< / p >
< h5 >
読み書きするファイルのフォーマット
< / h5 >
< p >
読み書きするファイルのフォーマットとして以下を想定したよ:
< / p >
< ul >
< li >
1行目に日付データ(エポックタイム)
< / li >
< / ul >
< p >
例えばこのようになります:
< / p >
< pre class = "syntax-highlight" >
% cat < span class = "synStatement" > test< / span > .dat
< span class = "synConstant" > 1234567890< / span > %
< / pre >
< h5 >
読み込む処理
< / h5 >
< p >
こんなのを想定しました:
< / p >
< ol >
< li >
ファイルが存在しなければ #f を返す
< / li >
< li >
ファイルが存在すれば、一行目を読み込む
< / li >
< li >
読み込んだ文字列を数値形式に変換し、数値形式の値を返す
< / li >
< li >
数値形式に変換できなければ、 #f を返す
< / li >
< li >
2行目以降は無視する
< / li >
< / ol >
< h5 >
書き込む処理
< / h5 >
< p >
こんなのを想定しました:
< / p >
< ol >
< li >
ファイルが存在しなければ、ファイルを作成してデータを書き込む
< / li >
< li >
ファイルが存在する場合は、上書きする
< / li >
< li >
書きこむデータとして与えられたのが数値であれば、数値として書きこむ
< / li >
< li >
書きこむデータとして与えられたのが文字列であれば、文字列として書き込む
< / li >
< li >
それ以外であれば、 #f を返す
< / li >
< / ol >
< h4 >
作成したソース
< / h4 >
< p >
作成したソースはこんな感じ:
< / p >
< pre class = "syntax-highlight" >
#!/usr/bin/env gosh
< span class = "synComment" > ;;; unit.test< / span >
< span class = "synSpecial" > (< / span > use gauche.test< span class = "synSpecial" > )< / span >
< span class = "synComment" > ;;; ファイルからの読み取り< / span >
< span class = "synSpecial" > (< / span > define < span class = "synSpecial" > (< / span > read-data-from-file path2file< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > with-input-from-file path2file
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > ()< / span >
< span class = "synSpecial" > (< / span > let1 < span class = "synConstant" > 1< / span > stline < span class = "synSpecial" > (< / span > < span class = "synStatement" > read-line< / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > string-> number < span class = "synConstant" > 1< / span > stline< span class = "synSpecial" > )))< / span >
< span class = "synType" > :if-does-not-exist</ span > #f < span class = "synSpecial" > ))</ span >
< span class = "synComment" > ;;; ファイルへの書き込み< / span >
< span class = "synSpecial" > (< / span > define < span class = "synSpecial" > (< / span > write-data-from-file path2file data< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > call-with-output-file path2file
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > port< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > cond< / span >
[< span class = "synSpecial" > (< / span > < span class = "synStatement" > number< / span > ? data< span class = "synSpecial" > )< / span > < span class = "synSpecial" > (< / span > begin
< span class = "synSpecial" > (< / span > < span class = "synStatement" > format< / span > port < span class = "synConstant" > " ~D" < / span > data< span class = "synSpecial" > )< / span >
#t<span class="synSpecial">)</span>]
[< span class = "synSpecial" > (< / span > < span class = "synStatement" > string< / span > ? data< span class = "synSpecial" > )< / span > < span class = "synSpecial" > (< / span > begin
< span class = "synSpecial" > (< / span > < span class = "synStatement" > format< / span > port < span class = "synConstant" > " ~A" < / span > data< span class = "synSpecial" > )< / span >
#t<span class="synSpecial">)</span>]
[else #f ]< span class = "synSpecial" > ))</ span >
< span class = "synType" > :if-does-not-exist< / span > < span class = "synType" > :create< / span > < span class = "synSpecial" > ))< / span >
< span class = "synComment" > ;;; test starts< / span >
< span class = "synSpecial" > (< / span > test-start < span class = "synConstant" > " ファイルの読み書き" < / span > < span class = "synSpecial" > )< / span >
< span class = "synComment" > ;;; 設定ファイルからの読み込み< / span >
< span class = "synSpecial" > (< / span > test-section < span class = "synConstant" > " ファイルからの読み込み" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " ファイルの1行目を読み込む" < / span >
< span class = "synConstant" > 1234567890< / span >
< span class = "synSpecial" > (< / span > read-data-from-file < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > expected result< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > =< / span > expected
result< span class = "synSpecial" > )))< / span >
< span class = "synComment" > ;;; 設定ファイルへの書き込み< / span >
< span class = "synSpecial" > (< / span > test-section < span class = "synConstant" > " 設定ファイルへの書き込み" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " 数値をファイルへ書き込む" < / span >
#t
< span class = "synSpecial" > (< / span > write-data-from-file < span class = "synConstant" > " ./test.dat" < / span >
< span class = "synConstant" > 1234567890< / span > < span class = "synSpecial" > ))< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " 数値が正常に書きこまれていることを確認する" < / span >
< span class = "synConstant" > 1234567890< / span >
< span class = "synSpecial" > (< / span > read-data-from-file < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > expected result< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > =< / span > expected
result< span class = "synSpecial" > )))< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " 文字列をファイルへ書き込む" < / span >
#t
< span class = "synSpecial" > (< / span > write-data-from-file < span class = "synConstant" > " ./test.dat" < / span >
< span class = "synConstant" > " 1234567890" < / span > < span class = "synSpecial" > ))< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " 文字列が正常に書きこまれていることを確認する" < / span >
< span class = "synConstant" > 1234567890< / span >
< span class = "synSpecial" > (< / span > read-data-from-file < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > expected result< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > =< / span > expected
result< span class = "synSpecial" > )))< / span >
< span class = "synSpecial" > (< / span > test-section < span class = "synConstant" > " 異常系" < / span > < span class = "synSpecial" > )< / span >
< span class = "synComment" > ;;; 設定ファイルを一時削除する< / span >
< span class = "synSpecial" > (< / span > sys-unlink < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (</ span > test* < span class = "synConstant" > " ファイルが存在しない場合は読み込み処理は #f を返す" </ span >
#f
< span class = "synSpecial" > (< / span > read-data-from-file < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > ))< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " エポックタイム形式以外のデータを書き込む" < / span >
#t
< span class = "synSpecial" > (< / span > write-data-from-file < span class = "synConstant" > " ./test.dat" < / span >
< span class = "synConstant" > " 123456789a" < / span > < span class = "synSpecial" > ))< / span >
< span class = "synSpecial" > (</ span > test* < span class = "synConstant" > " エポックタイム形式以外のデータを読み込んだ場合は #f を返す" </ span >
#f
< span class = "synSpecial" > (< / span > read-data-from-file < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > ))< / span >
< span class = "synComment" > ;;; 設定ファイルを一時削除する< / span >
< span class = "synSpecial" > (< / span > sys-unlink < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (</ span > test* < span class = "synConstant" > " ファイルが存在しない場合は、書き込み処理はファイル作成して #t を返す" </ span >
#t
< span class = "synSpecial" > (< / span > write-data-from-file < span class = "synConstant" > " ./test.dat" < / span >
< span class = "synConstant" > 1234567890< / span > < span class = "synSpecial" > ))< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " 正常に書きこまれていることを確認する" < / span >
< span class = "synConstant" > 1234567890< / span >
< span class = "synSpecial" > (< / span > read-data-from-file < span class = "synConstant" > " ./test.dat" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > expected result< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > =< / span > expected
result< span class = "synSpecial" > )))< / span >
< span class = "synSpecial" > (< / span > test-section < span class = "synConstant" > " 現状復帰" < / span > < span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > test* < span class = "synConstant" > " データファイルの回復" < / span >
#t
< span class = "synSpecial" > (< / span > write-data-from-file < span class = "synConstant" > " ./test.dat" < / span >
< span class = "synConstant" > " 1234567890" < / span > < span class = "synSpecial" > ))< / span >
< span class = "synSpecial" > (< / span > test-end< span class = "synSpecial" > )< / span >
< / pre >
< p >
実際に実行する場合は、事前にテストデータを作成してください。こんな感じです:
< / p >
< pre class = "syntax-highlight" >
% < span class = "synStatement" > echo< / span > < span class = "synConstant" > < / span > < span class = "synStatement" > " < / span > < span class = "synConstant" > 1234567890< / span > < span class = "synStatement" > " < / span > < span class = "synConstant" > < / span > < span class = "synStatement" > > < / span > < span class = "synStatement" > test< / span > .dat
< / pre >
< h4 >
実行結果
< / h4 >
< p >
実行するとこんな風になります:
< / p >
< pre class = "syntax-highlight" >
% ./< span class = "synConstant" > 2011-04-02-161017< / span > .scm
Testing ファイルの読み書き ...
< span class = "synStatement" > < < / span > ファイルからの読み込み< span class = "synStatement" > > < / span > ------------------------------------------------------------------
< span class = "synStatement" > test< / span > ファイルの< span class = "synConstant" > 1< / span > 行目を読み込む, expects < span class = "synConstant" > 1234567890< / span > < span class = "synStatement" > ==> < / span > ok
< span class = "synStatement" > < < / span > 設定ファイルへの書き込み< span class = "synStatement" > > < / span > -----------------------------------------------------------------
< span class = "synStatement" > test</ span > 数値をファイルへ書き込む, expects< span class = "synComment" > #t ==> ok</ span >
< span class = "synStatement" > test< / span > 数値が正常に書きこまれていることを確認する, expects < span class = "synConstant" > 1234567890< / span > < span class = "synStatement" > ==> < / span > ok
< span class = "synStatement" > test</ span > 文字列をファイルへ書き込む, expects< span class = "synComment" > #t ==> ok</ span >
< span class = "synStatement" > test< / span > 文字列が正常に書きこまれていることを確認する, expects < span class = "synConstant" > 1234567890< / span > < span class = "synStatement" > ==> < / span > ok
< span class = "synStatement" > < < / span > 異常系< span class = "synStatement" > > < / span > --------------------------------------------------------------------------
< span class = "synStatement" > test</ span > ファイルが存在しない場合は読み込み処理は< span class = "synComment" > #f を返す, expects #f ==> ok</ span >
< span class = "synStatement" > test</ span > エポックタイム形式以外のデータを書き込む, expects< span class = "synComment" > #t ==> ok</ span >
< span class = "synStatement" > test</ span > エポックタイム形式以外のデータを読み込んだ場合は< span class = "synComment" > #f を返す, expects #f ==> ok</ span >
< span class = "synStatement" > test</ span > ファイルが存在しない場合は、書き込み処理はファイル作成して< span class = "synComment" > #t を返す, expects #t ==> ok</ span >
< span class = "synStatement" > test< / span > 正常に書きこまれていることを確認する, expects < span class = "synConstant" > 1234567890< / span > < span class = "synStatement" > ==> < / span > ok
< span class = "synStatement" > < < / span > 現状復帰< span class = "synStatement" > > < / span > -------------------------------------------------------------------------
< span class = "synStatement" > test</ span > データファイルの回復, expects< span class = "synComment" > #t ==> ok</ span >
passed.
< / pre >
2019-04-02 16:06:15 +00:00
< / div >