BinaryReader 練習 (ReadChar)

會練習到這個,也是誤打誤撞
練習的內容是把前一陣子 dropbox 被駭的帳密轉到 db 中

讀取方式是透過 BinaryReader.ReadChar 的方式讀出
同時以換行字元(\r\n)做為各行的區隔

會寫成三個檔案是因為整個方案共有三個專案
把共用的部份取到 Common Class 中
再把 行處理 & 寫入 db 獨立至另一個 Class 中

主程式

using Data;
using System;
using System.Collections.Generic;

namespace DapperToDb
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 宣告

            var watch = new System.Diagnostics.Stopwatch();
            char c;   // 用來抓字元,抓完後,游標會移至下一個位置
            List<char> chars = new List<char>();     // 用來放整個 char 的

            AccountDapper ad = new AccountDapper();

            #endregion

            try
            {
                watch.Restart();

                #region 逐個 char 讀取

                while (Common.reader.PeekChar() != -1)
                {
                    if ((c = Common.reader.ReadChar()) == '\r')   // (int)'\r' = 13
                    {
                        if ((char)Common.reader.PeekChar() == '\n')  // (int)'\n' = 10
                        {

                            // 讓游標移至 \n 上
                            Common.reader.ReadChar();

                            #region 逐行處理

                            ad.lineToAccount(string.Join("", chars), false);
                            chars.Clear();

                            #endregion

                            continue;
                        }
                    }
                    chars.Add(c);
                }
                Common.readerClose();

                #endregion

                //讀取結束,把未寫入的處理
                ad.lineToAccount(string.Join("", chars), true);

                Console.WriteLine("全部讀取完畢");

                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Console.WriteLine("Time Cost:{0}", elapsedMs);
            }
            catch (Exception e)
            {
                Console.WriteLine("檔案處理失敗");
                Common.errorToFile(e.Message);
                Common.errorToFile(e.StackTrace);
            }

            Console.ReadLine();
        }
    }
}

Common Class

using System;
using System.IO;

namespace Data
{
    public class Common
    {
        public static string connectionString = @"Data Source=.\mssql2014;Initial Catalog=dropbox;Integrated Security=True";
        public static int maxCountToDb = 1000000;
        public static string file = @"../../../txt/bf_1.txt";

        private static FileStream _fileStream;
        private static BinaryReader _reader;
        
        public static BinaryReader reader
        {
            get
            {
                if (_reader != null) return _reader;

                _fileStream = File.Open(file, FileMode.Open, FileAccess.ReadWrite);
                _reader = new BinaryReader(_fileStream);

                return _reader;
            }
        }

        public static bool readerClose()
        {
            try
            {
                _fileStream.Close();
                _reader.Close();
                return true;
            }
            catch (Exception e)
            {
                Common.errorToFile(e.Message);
                Common.errorToFile(e.StackTrace);
                Console.ReadLine();
                return false;
            }
        }


        public static void errorToFile(string str)
        {
            TextWriter writer = new StreamWriter("error.txt", true);
            writer.Write(str + "\r\n");
            writer.Flush();
            writer.Close();
        }
    }
}

AccountDapper Class
 

using Dapper;
using Data;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace DapperToDb
{
    class AccountDapper
    {
        private Account _acc;
        private List<Account> _accounts = new List<Account>();

        public void lineToAccount(string line, bool end)
        {
            try
            {
                _acc = new Account(line);
                _accounts.Add(_acc);
                Console.Write('.');

                if (_accounts.Count >= Common.maxCountToDb || end)
                {
                    dapperWriteToDb(_accounts);
                    _accounts.Clear();
                }
            }
            catch (Exception e)
            {
                Common.errorToFile(line);
                Common.errorToFile(e.Message);
                Common.errorToFile(e.StackTrace);
                Console.ReadLine();
            }
        }
        public void dapperWriteToDb(List<Account> accounts)
        {          
            using (SqlConnection conn = new SqlConnection(Common.connectionString))
            {
                conn.Open();
                using (var trans = conn.BeginTransaction())
                {
                    var result = conn.Execute(@"INSERT INTO account(id,pw) VALUES(@id,@pw)", accounts, trans);
                    trans.Commit();
                }
            }
        }
    }
}

Account Class

using System;

namespace DapperToDb
{
    public class Account
    {
        public string id { get; set; }
        public string pw { get; set; }

        public Account(string line)
        {
            string[] lineArray = line.Split(':');
            if (lineArray[0].Trim().Length > 300) throw new Exception("id 太長");
            if (lineArray[1].Trim().Length > 70) throw new Exception("pw 太長");
            id = lineArray[0].Trim();
            pw = lineArray[1].Trim();
        }
    }
}

SQL Table 

CREATE TABLE [dbo].[account](
	[id] [nvarchar](300) NULL,
	[pw] [nvarchar](70) NULL,
	[no] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_account] PRIMARY KEY CLUSTERED 
(
	[no] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO