using System; using System.Collections.Generic; using System.Collections; using System.Text; using System.IO; using System.Xml.Serialization; using System.Threading; using System.Threading.Tasks; namespace randomWriter { public class configBase { public String writePath; public String filePrifix; public String fileSuffix; public String chars; public String terminate; public String encodingStr; public String[] basePaths; public int fileCount; public int lineWidth; public int lineCount; public int threadCount; public int dirThreadCount=1; public DateTime sDateTime = DateTime.Now; public DateTime eDateTime = DateTime.Now; public Boolean useRandomTimestamp = false; } public class config { private configBase cfgb; private int terminateLen = 2; private int maxCharByte = 0; private Random r = new Random(); private Dictionary char2ByteMap = new Dictionary(); private Dictionary index2StringMap = new Dictionary(); public config() { readConfig("config.xml"); checkConfig(); } public config(String filename) { readConfig(filename); checkConfig(); } public config(String filename, int dtc, int tc) { readConfig(filename); cfgb.threadCount = tc; cfgb.dirThreadCount = dtc; checkConfig(); } private void readConfig(String filename) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { XmlSerializer xs = new XmlSerializer(typeof(configBase)); cfgb = xs.Deserialize(fs) as configBase; fs.Close(); } } private void checkConfig() { /// fileCount,lineCount,lineWidth の設定値補正 if ((cfgb.fileCount > 999999) || (cfgb.fileCount < 1)) cfgb.fileCount = 1; if ((cfgb.lineCount > 99999999) || (cfgb.lineCount < 1)) cfgb.lineCount = 1; if ((cfgb.lineWidth > 99999999) || (cfgb.lineWidth < 1)) cfgb.lineWidth = 1; /// terminate で指定された改行文字列の長さ取得 terminateLen = Encoding.GetEncoding(cfgb.encodingStr).GetByteCount(cfgb.terminate); /// chars で指定された文字列を文字単位に分解して辞書に格納、文字で使用している最大バイト数確定 for (int i = 0; i < cfgb.chars.Length; i++) { index2StringMap[i] = cfgb.chars.Substring(i, 1); char2ByteMap[cfgb.chars.Substring(i, 1)] = Encoding.GetEncoding(cfgb.encodingStr).GetByteCount(cfgb.chars.Substring(i, 1)); if (maxCharByte < char2ByteMap[cfgb.chars.Substring(i, 1)]) maxCharByte = char2ByteMap[cfgb.chars.Substring(i, 1)]; } /// sDateTime,eDateTime の設定値補正 if (cfgb.sDateTime > cfgb.eDateTime) cfgb.eDateTime = cfgb.sDateTime; /// threadCount の設定値補正 int minwkr, minAIO; int maxwkr, maxAIO; int maxThreadsParDir; ThreadPool.GetMinThreads(out minwkr, out minAIO); ThreadPool.GetMaxThreads(out maxwkr, out maxAIO); /// ディレクトリ処理の並列数計算 if (cfgb.dirThreadCount < 1) cfgb.dirThreadCount = 3; if (cfgb.dirThreadCount > cfgb.basePaths.Length) cfgb.dirThreadCount = cfgb.basePaths.Length; /// ファイル生成スレッド数計算 if ((cfgb.threadCount > 100) || (cfgb.threadCount < minwkr)) cfgb.threadCount = minwkr; if (cfgb.threadCount > cfgb.fileCount) cfgb.threadCount = cfgb.fileCount; maxThreadsParDir = maxwkr / cfgb.dirThreadCount; if (cfgb.threadCount > maxThreadsParDir) cfgb.threadCount = maxThreadsParDir; /// 並列処理は無理 if (maxThreadsParDir == 0) { cfgb.dirThreadCount = 1; cfgb.threadCount = 1; } } public String WritePath { get { return cfgb.writePath; } } public String[] BasePaths { get { return cfgb.basePaths; } } public String FilePrifix { get { return cfgb.filePrifix; } } public String FileSuffix { get { return cfgb.fileSuffix; } } public String Terminate { get { return cfgb.terminate; } } public int TerminateLen { get { return terminateLen; } } public int FileCount { get { return cfgb.fileCount; } } public int LineCount { get { return cfgb.lineCount; } } public int LineWidth { get { return cfgb.lineWidth; } } public int ThreadCount { get { return cfgb.threadCount; } } public int DirThreadCount { get { return cfgb.dirThreadCount; } } public String EncodingStr { get { return cfgb.encodingStr; } } public Encoding EncodingObj { get { return Encoding.GetEncoding(cfgb.encodingStr); } } public DateTime RandomDateTime { get { return cfgb.sDateTime.AddMilliseconds(r.NextDouble() * (cfgb.eDateTime - cfgb.sDateTime).TotalMilliseconds); } } public Boolean UseRandomTimestamp { get { return cfgb.useRandomTimestamp; } } public int MaxCharByte { get { return maxCharByte; } } public int MaxCharsLen { get { return cfgb.chars.Length; } } public void initThreadSize() { int minwkr, minAIO; int newMinwkr = cfgb.threadCount * cfgb.dirThreadCount; ThreadPool.GetMinThreads(out minwkr, out minAIO); ThreadPool.SetMinThreads(newMinwkr, minAIO); } public String idx2Str(int idx) { return index2StringMap[idx]; } public int idx2byte(int idx) { return char2ByteMap[ idx2Str(idx) ]; } public int char2Byte(String s) { return char2ByteMap[s]; } public void writeconfig(String filename) { FileStream fs = new FileStream(filename, FileMode.Create); XmlSerializer xs = new XmlSerializer(typeof(configBase)); xs.Serialize(fs, cfgb); fs.Close(); } public Boolean mkFile(String filePath, Int32 seed1, Int32 seed2) { Encoding eobj = EncodingObj; Byte[] buff = new Byte[LineWidth * MaxCharByte + TerminateLen]; Boolean ans = true; Random q = new Random(Environment.TickCount + seed1 + seed2); using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { int bufsize = 0; int sidx = 0; try { for (int lc = 0; lc < LineCount; lc++) { bufsize = 0; for (int wi = 0; wi < LineWidth; wi++) { sidx = q.Next(0, MaxCharsLen); eobj.GetBytes(idx2Str(sidx)).CopyTo(buff, bufsize); bufsize += idx2byte(sidx); } eobj.GetBytes(Terminate).CopyTo(buff, bufsize); bufsize += TerminateLen; fs.Write(buff, 0, bufsize); } fs.Flush(); fs.Close(); fs.Dispose(); } catch (Exception e) { Console.WriteLine("{0} {1} - {2}", DateTime.Now, filePath, e.Message); ans = false; } } return ans; } public Boolean mkFolder(String folderPath) { Boolean ans = true; if (Directory.Exists(folderPath) == false) { try { Directory.CreateDirectory(folderPath); } catch (Exception e) { Console.WriteLine("{0} {1} - {2}", DateTime.Now, folderPath, e.Message); ans = false; } } return ans; } public Boolean modFile(String filePath) { Boolean ans = true; DateTime rt = RandomDateTime; if ((UseRandomTimestamp == true) && (File.Exists(filePath) == true)) { try { File.SetCreationTime(filePath, rt); File.SetLastWriteTime(filePath, rt); File.SetLastAccessTime(filePath, rt); } catch (Exception e) { Console.WriteLine("{0} {1} - {2}", DateTime.Now, filePath, e.Message); ans = false; } } return ans; } public Boolean modFolder(String folderPath) { Boolean ans = true; DateTime rt = RandomDateTime; if ((UseRandomTimestamp == true) && (Directory.Exists(folderPath) == true)) { try { Directory.SetCreationTime(folderPath, rt); Directory.SetLastWriteTime(folderPath, rt); Directory.SetLastAccessTime(folderPath, rt); } catch (Exception e) { Console.WriteLine("{0} {1} - {2}", DateTime.Now, folderPath, e.Message); ans = false; } } return ans; } } class Program { static void Main(string[] args) { config cfg; Action[] t; DateTime s; DateTime e; switch (args.Length) { case 2: cfg = new config("config.xml", Int32.Parse(args[0]), Int32.Parse(args[1])); break; default: cfg = new config("config.xml"); break; } cfg.initThreadSize(); //cfg.writeconfig("xconfig.xml"); s = DateTime.Now; Console.WriteLine("{0} start", s); Console.WriteLine(" {0} Dirctories", cfg.BasePaths.Length); Console.WriteLine(" {0} dirThreadCount", cfg.DirThreadCount); Console.WriteLine(" {0} threadCount", cfg.ThreadCount); for (int bpc = 0; bpc < cfg.BasePaths.Length; bpc += cfg.DirThreadCount) { int dtc = cfg.DirThreadCount; if ((bpc + dtc) > cfg.BasePaths.Length) dtc = cfg.BasePaths.Length % cfg.DirThreadCount; for (int cfc = 0; cfc < cfg.FileCount; cfc += cfg.ThreadCount) { int tc = cfg.ThreadCount; if ((cfc + tc) > cfg.FileCount) tc = cfg.FileCount % cfg.ThreadCount; t = new Action[dtc * tc]; for (int idtc = 0; idtc < dtc; idtc++) { for (int itc = 0; itc < tc; itc++) { int localbpc = bpc; int localidtc = idtc; int localtc = tc; int localdtc = dtc; int localcfc = cfc; int localitc = itc; String writePath = cfg.WritePath + "\\" + cfg.BasePaths[localbpc + localidtc]; t[(localidtc * localtc) + localitc] = () => { String fileName = String.Format(@"{0}\{1}{2:D06}{3}", writePath, cfg.FilePrifix, localcfc + localitc, cfg.FileSuffix); cfg.mkFolder(writePath); cfg.mkFile(fileName, localbpc + localidtc, localcfc + localitc); if (cfg.UseRandomTimestamp == true) cfg.modFile(fileName); }; } } Parallel.Invoke(t); } if (cfg.UseRandomTimestamp == true) { for (int idtc = 0; idtc < dtc; idtc++) { String writePath = cfg.WritePath + "\\" + cfg.BasePaths[bpc + idtc]; cfg.modFolder(writePath); } } Console.WriteLine("{0} {1} Dirs processed.", DateTime.Now, dtc); } e = DateTime.Now; Console.WriteLine("{0} end, {1}", e, e - s); } } }