LoginSignup
0
3

More than 5 years have passed since last update.

[ C#]ファイルの排他制御について(お力を貸してください)

Last updated at Posted at 2017-12-15

ファイルを読み込み、そのファイルに記載されているキーに紐付く値を更新するとします。※引数からもらったキーに紐づく値のみを変更し、変更していないキーや値も含めファイルを上書きしています。

これは普通に書けるのですが、多重処理になったときに、参照と更新のタイミングによりあるキーに対する更新が無かったことになってしまう場合があります。

やりたいのは
①ファイルに対して他プロセスからの読み取り不可のロックをかける
②ファイル内容を読み取る
③引数にて渡されたキーに紐づく値を変更し、ファイルに対して更新をかける
④①でかけたロックを外す

FileStreamで①はできて、読み取りも出来たのですが、ファイル更新をしようとstreamWriterにstreamを渡した瞬間に例外が発生します。

メッセージは「ストリームが出力できませんでした」※うる覚えです
が出力されています。

FileSptreamは
Open
ReadWrite
Noneで指定しております。

あまり調べてもピッタリの事象がなくて困っています。そもそもの方針がセンスないのでしょうか。

皆様のお力をお貸しください。

↓書き込めない事象は解決しました。
が、上書き処理ではなく追記になってしまうため困っております。。。

test.cs

        /// <param name="updKey"></param>
        private static void Update(string updKey)
        {

            /* ------------------------------*/
            // 日付更新ファイルから日付を取得
            /* ------------------------------*/
            string filePath = @"C:\TEST\Date.txt";
            Dictionary<string, string> dictionary = new Dictionary<string, string>();

            // 排他ロックをかける
            System.IO.FileStream fs = new System.IO.FileStream(
            filePath,
            System.IO.FileMode.OpenOrCreate,
            System.IO.FileAccess.ReadWrite,
            System.IO.FileShare.None);

            // ファイル読込
            TextFieldParser parser = new TextFieldParser(fs, Encoding.GetEncoding("Shift_JIS"));
            parser.TextFieldType = FieldType.Delimited;
            parser.SetDelimiters(",");

            List<string[]> dataList = new List<string[]>();
            while (!parser.EndOfData)
            {
                dataList.Add(parser.ReadFields());
            }

            foreach (string[] array in dataList)
            {
                dictionary.Add(array[0], array[1]);
            }

            /* ------------------------------*/
            // キーに紐づく日付の加算
            /* ------------------------------*/
            DateTime dateTime = new DateTime();
            string[] keys = new string[dictionary.Keys.Count];
            dictionary.Keys.CopyTo(keys, 0);

            foreach (string key in keys)
            {
                if (key.Contains(updKey))
                {
                    dateTime = DateTime.Parse(dictionary[key]);
                    dateTime = dateTime.AddDays(1);
                    dictionary[key] = dateTime.ToString("yyyy/MM/dd");
                }
            }

            /* ------------------------------*/
            // 一つの文字列に格納
            /* ------------------------------*/
            StringBuilder sb = new StringBuilder();
            foreach (string key in keys)
            {
                sb.Append(key + "," + dictionary[key] + "\r\n");
            }


            /* ------------------------------*/
            // 更新処理
            /* ------------------------------*/
            bool flg = false;
            for (int i = 0; i < 5; i++)
            {
                StreamWriter sw;
                try
                {
                    using (sw = new StreamWriter(fs, Encoding.GetEncoding("Shift_JIS")))
                    {
                        sw.Write(sb.ToString());
                        flg = true;
                        break;
                    }
                }
                catch(Exception e)
                {
                }
            }

            if (!flg)
            {
                // 失敗 

            }
            {
                // 成功
            }

            return;


'''
0
3
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3