233 lines
14 KiB
Markdown
233 lines
14 KiB
Markdown
---
|
|
title: ファイルの読み書き
|
|
author: kazu634
|
|
date: 2011-04-02
|
|
url: /2011/04/02/_1670/
|
|
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>
|
|
</div> |