- PR -

ファイルへ部分的な上書き

投稿者投稿内容
kinta
会議室デビュー日: 2003/07/07
投稿数: 3
投稿日時: 2003-12-10 11:09
kintaと申します。
ファイル操作にてファイルの一部分を書き替える場合、
例えば:
9[改行]
11[EOF]
というファイルの中身だとして、1行目の"9"→"10"にすると、
1行目の改行コードを上書きしてしまい、
1011[EOF]となってしまいます。
1Byte増える程度ならWindows上の改行コードは2Byteなので1Byteだけ
上書きされなんとか1行目と2行目がなりたちますが、
UnixなどのLFのみの改行コードでは上記のように行の区切り文字(改行文字)
を上書きしてしまいますし、増加分が2Byte以上になるとどうしようもありません。
このような場合の対処方法ついてご意見を頂きたいと思います。

ちなみに、今、考えている対応策はtempファイルを作成し、
内容を書き換える方法や、想定される増加分のバイト領域を改行手前に
空白として領域確保するといった方法ですが、
対象ファイルはサイズがものすごく大きいので、tempは作成したくなく、
できればこういった事象に対応したclassがあることを望んでおります。
現在、RandomAccessFileクラスを使用し、seek()後、writeBytes()にて書き込んでます。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2003-12-10 11:38
考え方は尽くされていますね
一本につながったものの部分変更は全面書き換えになります
予備の記憶域は固定長項目などにつながる考え方でしょう
DB ソフトは「そのようなこと」を行っています。

元データ+変更差分を別々に管理する系統のもあります
プログラムソース管理の製品群では
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-10 12:35
各行に書かれているデータのバイト数がそれほど変動しないのであれば、固定長を
採用するのが良いかなと思います。
例えば、改行コードは<LF>で固定するとして、行の先頭には有効データバイト数を
表す数字を1バイトだけ確保し、1行のデータバイト数を126バイトとすると、
コード:
(1行のバイト数)
 =(有効データバイト数を表す1バイト)+(1行のデータ126バイト)+(改行コード1バイト)
 =128バイト


てな感じになりますね。
で、n行目のデータの読み出しは

  • ファイルの先頭に移動
  • n×128バイトシーク
  • 1バイト読み出し
  • 読み出したバイトの値分だけ更に読み出してデータとして取得

でできるかな。

書き出しは、126バイトまでだったら可能で、その際に有効バイト数を記録するのを
忘れないようにする、という感じですかね。

固定長ってやったこと無いんで、間違ってたらすみません。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-12-10 13:24
別の方法として、インデックスファイルと実体ファイルの二本立てで保存するという方法もあります。データは適当な方法で実体ファイルに保存し、その保存データへのオフセットをインデックスファイルに保存します。

指定したインデックスのデータを変更したい場合は、実体ファイルの末尾にデータを追加し、元の保存データは消します。ついで、インデックスファイルのオフセット値を変更してやります。
# 通常は全部消さずにフラグを立てるだけなのかな?

こうすると自由に書き換えできるのですが、実体ファイルサイズが増大していきます。そのため、適宜、不要なデータをコンパクション(圧縮)し、インデックスファイルのオフセット値を変更してやります。

インデックスファイルは固定長のファイルなので、更新は容易でしょう。またサイズもそれほど大きくはならないと思います。

作成は困難ですが、一度ライブラリ化してしまえば使いまわしできます。
ただ、ここまでするなら、DB使えば?って気もします。
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-10 14:56
引用:

ただ、ここまでするなら、DB使えば?って気もします。


UNIXだと、ファイルベースでDBライクに使えるBerkley DBというライブラリがありますよね。
Javaであれに相当するようなものって無いのでしょうか?
どなたかご存知ありませんか?
kinta
会議室デビュー日: 2003/07/07
投稿数: 3
投稿日時: 2003-12-10 15:05
回答ありがとうございました。

みなさんの回答をみる限りやはり
ファイル側の仕様を変えて対応するしか無いようですね。
私が知らなかっただけで、すばらしく使い勝手
の良いAPIが眠っていたりしないかと、
期待はしていましたが。。
というかファイルの構造的には無理な気はしますが、
JavaAPIでこんな事象に対応したCLASSは提供されないんでしょうか?
使い方はRandomAccessFileと同じような感じで、
裏ではtempファイルを作成してファイルの編集を行なうような。。。
甘い考えなのでしょうか?
多分需要はあると思うのですが。ないんでしょうか?
聞くところによるとC言語では可能らしいんですよ。
Cはまったく分からないんで試していませんが。
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2003-12-10 15:31
引用:

kintaさんの書き込み (2003-12-10 15:05) より:
聞くところによるとC言語では可能らしいんですよ。
Cはまったく分からないんで試していませんが。



初めて聞きました。よろしければその情報の出所をお教えいただけますか。


自作するとなると、

・元ファイル
・編集履歴(どこからどこまでを消去、どこに何を挿入、など)

を管理して、最後に別ファイルに書き出し、というライブラリになりますかね。

...なんかすでに誰かが作っていそうな気がします。googleなどで検索はされましたか?
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-10 15:32
引用:

聞くところによるとC言語では可能らしいんですよ。


本当ですか??
UNIXのシステムコールやCの標準ライブラリは大体覚えている(とは言ってももう4年
位書いてないですが、、、)のですが、そのような関数は記憶に無かった気が。
そういう機能を提供する特別なライブラリがあるのかな??

スキルアップ/キャリアアップ(JOB@IT)