出会いセンター C#からマルチストリームを扱う方法

C#からマルチストリームを扱う方法

ファイルに関する概要情報の取得」で紹介した、マルチストリームをC#から扱う方法について解説します。 マルチストリームに関しては「ファイルに関する概要情報の取得」のほうで簡単に解説しているのでそちらを 参考にしてください。

ファイルハンドルはCreateFile()で取得する

通常C#からファイルを扱う場合にはFileStreamクラスを使用します。しかし、このFileStreamクラスは マルチストリームをサポートしていません。従って、下記に示すような書式を用いてマルチストリームを 扱うことはできないようです。

[ファイル名]:[ストリーム名]
(例 test.txtというファイルのInformationというストリームの場合)
test.txt:Information

そこでCreateFileというAPI関数を用いてファイルハンドルを取得し、そのハンドルを元にFileStreamを 生成する方法が考えられます。実は、FileSystemObjectをはじめとするマルチストリームをサポートする クラス等は内部でCreateFileを使用しています。では、簡単なサンプルプログラムを以下に示します。 (C:\test.txtが存在することを前提としています。)

using System;
using System.Runtime.InteropServices;
using System.IO;

namespace MultiStreamSample
{
    class Class1
    {
        #region Win32 API宣言

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr CreateFile(
            string lpFileName, // ファイル名
            DesiredAccess dwDesiredAccess, // アクセスモード
            ShareMode dwShareMode, // 共有モード
            int lpSecurityAttributes, // セキュリティ記述子
            CreationDisposition dwCreationDisposition, // 作成方法
            FlagsAndAttributes dwFlagsAndAttributes, // ファイル属性
            IntPtr hTemplateFile // テンプレートファイルのハンドル
            );

        #region 列挙体

        private enum DesiredAccess : uint
        {
            GENERIC_READ = 0x80000000,
            GENERIC_WRITE = 0x40000000,
            GENERIC_EXECUTE = 0x20000000
        }

        private enum ShareMode : uint
        {
            FILE_SHARE_READ = 0x00000001,
            FILE_SHARE_WRITE = 0x00000002,
            FILE_SHARE_DELETE = 0x00000004
        }

        private enum CreationDisposition : uint
        {
            CREATE_NEW = 1,
            CREATE_ALWAYS = 2,
            OPEN_EXISTING = 3,
            OPEN_ALWAYS = 4,
            TRUNCATE_EXISTING = 5
        }

        private enum FlagsAndAttributes : uint
        {
            FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
            FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
            FILE_ATTRIBUTE_HIDDEN = 0x00000002,
            FILE_ATTRIBUTE_NORMAL = 0x00000080,
            FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
            FILE_ATTRIBUTE_OFFLINE = 0x00001000,
            FILE_ATTRIBUTE_READONLY = 0x00000001,
            FILE_ATTRIBUTE_SYSTEM = 0x00000004,
            FILE_ATTRIBUTE_TEMPORARY = 0x00000100
        }

        #endregion

        #endregion

        [STAThread]
        static void Main(string[] args)
        {
            Console.WriteLine("書き込みの開始");
            IntPtr fileHandle = CreateFile(@"C:\test.txt:config",
                                            DesiredAccess.GENERIC_WRITE,
                                            ShareMode.FILE_SHARE_READ, 0,
                                            CreationDisposition.OPEN_ALWAYS,
                                            FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL,
                                            IntPtr.Zero);
            using(StreamWriter sw = new StreamWriter(new FileStream(fileHandle,
                                                         FileAccess.Write)))
            {
                sw.WriteLine("書き込みテスト用文字列");
            }
            Console.WriteLine("書き込み完了" + Environment.NewLine);
            Console.WriteLine("読み込み開始");
            fileHandle = CreateFile(@"C:\test.txt:config",
                                    DesiredAccess.GENERIC_READ,
                                    ShareMode.FILE_SHARE_READ, 0,
                                    CreationDisposition.OPEN_ALWAYS,
                                    FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            using(StreamReader sr = new StreamReader(new FileStream(fileHandle,
                                                         FileAccess.Read)))
            {
                Console.WriteLine("---------------------");
                Console.WriteLine(sr.ReadToEnd());
                Console.WriteLine("---------------------");
            }
            Console.WriteLine("読み込み終了");
        }
    }
}

さて、これを利用してアプリケーションの設定をストリームに保存してみようと思います。 この方法はNTFSをサポートするOSでしか機能しませんが、初期化ファイルのように 誤って削除、改変される等の心配がなくなります。また、実行ファイルと一体なので移動やコピー のときにも便利でしょう。では、簡単なサンプルです。

#region using

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

#endregion

namespace SerializeOnNTFSStream
{
    /// <summary>
    /// Form1
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        /// <summary>
        /// 保存するデータを格納しておく
        /// </summary>
        [Serializable]
        public class SettingData
        {
            public Point FormLocation;
            public Size FormSize;
            public SettingData(Point location, Size size)
            {
                FormLocation = location;
                FormSize = size;
            }
        }

        private System.ComponentModel.Container components = null;

        #region Win32 API宣言

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr CreateFile(
            string lpFileName, // ファイル名
            DesiredAccess dwDesiredAccess, // アクセスモード
            ShareMode dwShareMode, // 共有モード
            int lpSecurityAttributes, // セキュリティ記述子
            CreationDisposition dwCreationDisposition, // 作成方法
            FlagsAndAttributes dwFlagsAndAttributes, // ファイル属性
            IntPtr hTemplateFile // テンプレートファイルのハンドル
            );

        #region 列挙体

        private enum DesiredAccess : uint
        {
            GENERIC_READ = 0x80000000,
            GENERIC_WRITE = 0x40000000,
            GENERIC_EXECUTE = 0x20000000
        }

        private enum ShareMode : uint
        {
            FILE_SHARE_READ = 0x00000001,
            FILE_SHARE_WRITE = 0x00000002,
            FILE_SHARE_DELETE = 0x00000004
        }

        private enum CreationDisposition : uint
        {
            CREATE_NEW = 1,
            CREATE_ALWAYS = 2,
            OPEN_EXISTING = 3,
            OPEN_ALWAYS = 4,
            TRUNCATE_EXISTING = 5
        }

        private enum FlagsAndAttributes : uint
        {
            FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
            FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
            FILE_ATTRIBUTE_HIDDEN = 0x00000002,
            FILE_ATTRIBUTE_NORMAL = 0x00000080,
            FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
            FILE_ATTRIBUTE_OFFLINE = 0x00001000,
            FILE_ATTRIBUTE_READONLY = 0x00000001,
            FILE_ATTRIBUTE_SYSTEM = 0x00000004,
            FILE_ATTRIBUTE_TEMPORARY = 0x00000100
        }

        #endregion

        #endregion


        #region コンストラクタ

        public Form1()
        {
            InitializeComponent();
        }

        #endregion

        #region Dispose 処理

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #endregion

        #region Windows フォーム デザイナで生成されたコード

        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            //
            // Form1
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.Closed += new System.EventHandler(this.Form1_Closed);

        }

        #endregion

        #region メインエントリポイント

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        #endregion

        private void Form1_Load(object sender, System.EventArgs e)
        {
            IFormatter formatter = new BinaryFormatter();
            IntPtr fileHandle = CreateFile(Application.ExecutablePath + ":setting",
                DesiredAccess.GENERIC_READ,
                ShareMode.FILE_SHARE_READ, 0,
                CreationDisposition.OPEN_EXISTING,
                FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            if(fileHandle.ToInt32() != -1)
            {
                using(Stream s = new FileStream(fileHandle, FileAccess.Read))
                {
                    SettingData setting = (SettingData)formatter.Deserialize(s);
                    this.Location = setting.FormLocation;
                    this.Size = setting.FormSize;
                }
            }

        }

        private void Form1_Closed(object sender, System.EventArgs e)
        {
            IFormatter formatter = new BinaryFormatter();
            IntPtr fileHandle = CreateFile(Application.ExecutablePath + ":setting",
                DesiredAccess.GENERIC_WRITE,
                ShareMode.FILE_SHARE_READ, 0,
                CreationDisposition.OPEN_ALWAYS,
                FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            if(fileHandle.ToInt32() != -1)
            {
                using(Stream s = new FileStream(fileHandle, FileAccess.Write))
                {
                    SettingData setting = new SettingData(this.Location, this.Size);
                    formatter.Serialize(s, setting);
                }
            }
        }
    }
}

フォームの位置とサイズをシリアル化を使用して保存しています。動作を確認するときは、Visual Studio等のIDEから 開始(実行)してはいけません。これは自分のファイル自身に書き込んでいるためです。従って、実行ファイルを 単独で実行してください。(エクスプローラー等からアイコンをダブルクリック)

無料 出会い系 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料出会い 無料 出会い系 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料 出会い掲示板 アクセスカウンター 無料 出会い 無料 出会い 無料 出会い デリヘル 広島 無料出会い 無料 出会い 無料 出会い 印鑑 アダルト動画 無料 出会い系 無料 出会い 無料 出会い 無料 出会い 無料 出会い 無料出会い 無料 出会い系 無料 出会い 無料 出会い 無料出会い 無料 出会い 無料 出会い オオクワガタ 無料 出会い