バイナリデータをテキスト化して出力,処理最終段で
ヘッダとして利用している先頭部分に,このファイルのデータブロック総行数を書き込まないといけなくなったもんで
まぁ,行数が数1000行ぐらいなら,StreamReader,StreamWriterあたりを使って
再読み込み~書き換え~別ファイルとして保存,って手がお手軽じゃけど...
対象は最大数10万行に達する可能性も
たった1箇所の書き換えに,このやり方はオーバーヘッドが洒落にならん!
ってことで.ちょいと書き起こしてみたが,これがテゲ面倒じゃった
まずは,書き換え対象のファイル
aaaa
iiii
1くまさんだぁ~
マキマキらぶ
hogehoge
%TEST%
まだまだ続くヨォ~
空行も挟んだ
エヴァンゲリオン
もういいじゃろ?
これで終わり
'%TEST%'(6文字分)って文字を置き換えます
して,ソース
FileStreamを使って,バイナリモードでテキストファイルを読み込み
改行を検出したら,バイナリを文字列化
'%TEST%'を'CHG 'に置き換えます.置き換え後の文字byte数は,置き換える前のバイト数と同じにしておかないと,トラブりまする
んで,先頭からのバイト数を加算しておき,置き換え処理を行うときは,
FileStream.Seek()で,ファイルポインタを戻して,バイナリモードで書き換えて,処理完了,って流れです
ちとソースが長いですが,参考にドゾー
C#:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- namespace filereplace
- {
- public partial class Form1 : Form
- {
- private const string REPLACESTR = "%TEST%";
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- System.IO.FileStream fs = System.IO.File.Open( "z:\\replacetest.txt",
- System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite );
- byte[] writebuf = null;
- int readbufoffset = 0;
- long fileoffset = 0;
- bool filejobfl = true;
- while (fs.Position <fs.Length)
- {
- if ((readbufoffset + 10)>= readbuf.Length) //改行コードを見つけられずにバッファオーバーした場合
- {
- //なんらかのエラー処理
- break;
- }
- int readresult = fs.Read(readbuf, readbufoffset, 10);
- if (readresult == 0)
- {
- break;
- }
- else
- {
- readbufoffset += readresult;
- }
- bool LoopFL = true;
- while(LoopFL == true)
- {
- int cridx = 0;
- bool crfl = CheckCR(readbuf, out cridx);
- if ( crfl == true)
- {
- Array.Copy(readbuf, tmpbuf, cridx+2);
- string st = Encoding.GetEncoding("shift_jis").GetString(tmpbuf);
- MoveAry(readbuf, cridx+2); //前に詰める
- readbufoffset -= cridx+2; //バッファの最終位置を調整
- if (st.IndexOf(REPLACESTR)>= 0)
- {
- st.Replace(REPLACESTR, "CHG "); //%TEST%をCHG に置き換え
- fs.Seek(fileoffset, System.IO.SeekOrigin.Begin);
- writebuf = Encoding.GetEncoding("shift_jis").GetBytes("CHG ");
- fs.Write(writebuf, 0, writebuf.Length);
- filejobfl = false;
- LoopFL = false;
- break;
- }
- byte[] dmybuf = Encoding.GetEncoding("shift_jis").GetBytes(st); //先頭からのbyte長を加算
- fileoffset += dmybuf.Length;
- }
- else
- {
- LoopFL = false;
- }
- }
- if (filejobfl == false)
- {
- break;
- }
- }
- fs.Close();
- }
- //改行コードの発見
- private bool CheckCR(byte[] buf, out int Idx)
- {
- Idx = -1;
- for(int i = 0; i <buf.Length; i++)
- {
- if ((i + 1)>= buf.Length)
- {
- return false;
- }
- if ((buf[i] == '\r') && (buf[i+1] == '\n'))
- {
- Idx = i;
- return true;
- }
- }
- return false;
- }
- //配列を前に詰める
- private void MoveAry(byte[] buf, int mvCount)
- {
- for(int i =0; i <buf.Length; i++)
- {
- if ((i + mvCount)>= buf.Length)
- {
- break;
- }
- if (buf[i + mvCount] == '\0')
- {
- for( int j = i; j <buf.Length; j++)
- {
- buf[j] = (byte)'\0';
- }
- break;
- }
- buf[i] = buf[i + mvCount];
- }
- }
- }
- }