diff --git a/CsvIndexer.cs b/CsvIndexer.cs new file mode 100644 index 0000000..6a4607a --- /dev/null +++ b/CsvIndexer.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace CsvView +{ + public class CsvIndexer + { + private bool _insideString = false; + + private char _separator = ','; + private char _quoteChar = '"'; + private char _escapeChar = '\\'; + + public CsvIndexer(char separator = ',', char quoteChar = '"', char escapeChar = '\\') + { + _separator = separator; + _quoteChar = quoteChar; + _escapeChar = escapeChar; + } + + private List _index = new List(); + + public List Index { get { return _index; } } + + private void DummyParser(string line) + { + for (int i = 0; i < line.Length; i++) + { + char c = line[i]; + if (c == _separator && _insideString == false) + { + continue; + } + if (c == _quoteChar && _insideString == false) + { + _insideString = true; + continue; + } + if (c == _quoteChar && _insideString == true) + { + _insideString = false; + continue; + } + if (c == _escapeChar && _insideString) + { + i++; + c = line[i]; + } + } + } + + private class TrackingTextReader : TextReader + { + private TextReader _baseReader; + private int _position; + + public TrackingTextReader(TextReader baseReader) + { + _baseReader = baseReader; + } + + public override int Read() + { + _position++; + return _baseReader.Read(); + } + + public override int Peek() + { + return _baseReader.Peek(); + } + + public int Position + { + get { return _position; } + } + } + + public void GenerateIndex(string file) + { + _insideString = false; + _index.Clear(); + FileStream stream = new FileStream(file, FileMode.Open); + using (StreamReader streamReader = new StreamReader(stream, Encoding.Default, true, 4096)) + using (TrackingTextReader reader = new TrackingTextReader(streamReader)) + { + string currentLine; + if (_insideString == false) + { + _index.Add(reader.Position); + } + while ((currentLine = reader.ReadLine()) != null) + { + DummyParser(currentLine); + if (_insideString == false) + { + _index.Add(reader.Position); + } + } + } + stream.Close(); + } + + private void Index_SaveFile(string indexFile) + { + if (File.Exists(indexFile)) + { + File.Delete(indexFile); + } + Stream streamOut = File.Open(indexFile, FileMode.Create); + using (BinaryWriter binWriter = new BinaryWriter(streamOut)) + { + binWriter.Write(_index.Count); + for (int i = 0; i < _index.Count; i++) + { + binWriter.Write(_index[i]); + } + } + streamOut.Close(); + } + + private static List Index_LoadFile(string indexFile) + { + var tempIndex = new List(); + + Stream streamIn = File.Open(indexFile, FileMode.Open); + using (BinaryReader binReader = new BinaryReader(streamIn)) + { + int numRegs = binReader.ReadInt32(); + for (int i = 0; i < numRegs; i++) + { + long value = binReader.ReadInt64(); + tempIndex.Add(value); + } + } + streamIn.Close(); + return tempIndex; + } + + public void LoadIndexOfFile(string file) + { + DateTime dtFile = File.GetCreationTime(file); + string indexFile = file + ".idx"; + if (File.Exists(indexFile) && File.GetCreationTime(indexFile) > dtFile) + { + _index = Index_LoadFile(indexFile); + } + else + { + // Generate index + DateTime dtNow = DateTime.UtcNow; + GenerateIndex(file); + TimeSpan tsGenIndex = DateTime.UtcNow - dtNow; + + // Save Index if expensive generation + if (tsGenIndex.TotalSeconds > 2) + { + Index_SaveFile(indexFile); + } + } + } + } +} diff --git a/CsvParser.cs b/CsvParser.cs index 5a71114..c5621ae 100644 --- a/CsvParser.cs +++ b/CsvParser.cs @@ -23,7 +23,7 @@ namespace CsvView private List _currentReg = null; StringBuilder _currentCell = null; - + public List> Data { get { return _data; } @@ -31,15 +31,15 @@ namespace CsvView public void ParseLine(string line) { - if(_currentReg == null) + if (_currentReg == null) { _currentReg = new List(); } - if(_currentCell == null) + if (_currentCell == null) { _currentCell = new StringBuilder(); } - + for (int i = 0; i < line.Length; i++) { char c = line[i]; @@ -96,7 +96,7 @@ namespace CsvView while ((currentLine = reader.ReadLine()) != null) { ParseLine(currentLine); - if(count>0 && Data.Count== count) + if (count > 0 && Data.Count == count) { break; } @@ -104,89 +104,6 @@ namespace CsvView } stream.Close(); } - - private List _index = new List(); - - public List Index { get { return _index; } } - - private void DummyParser(string line) - { - for (int i = 0; i < line.Length; i++) - { - char c = line[i]; - if (c == _separator && _insideString == false) - { - continue; - } - if (c == _quoteChar && _insideString == false) - { - _insideString = true; - continue; - } - if (c == _quoteChar && _insideString == true) - { - _insideString = false; - continue; - } - if (c == _escapeChar && _insideString) - { - i++; - c = line[i]; - } - } - } - - private class TrackingTextReader : TextReader - { - private TextReader _baseReader; - private int _position; - - public TrackingTextReader(TextReader baseReader) - { - _baseReader = baseReader; - } - - public override int Read() - { - _position++; - return _baseReader.Read(); - } - - public override int Peek() - { - return _baseReader.Peek(); - } - - public int Position - { - get { return _position; } - } - } - - public void GenerateIndex(string file) - { - _insideString = false; - _index.Clear(); - FileStream stream = new FileStream(file, FileMode.Open); - using (StreamReader streamReader = new StreamReader(stream, Encoding.Default, true, 4096)) - using (TrackingTextReader reader = new TrackingTextReader(streamReader)) - { - string currentLine; - if (_insideString == false) - { - _index.Add(reader.Position); - } - while ((currentLine = reader.ReadLine()) != null) - { - DummyParser(currentLine); - if (_insideString == false) - { - _index.Add(reader.Position); - } - } - } - stream.Close(); - } - + } } diff --git a/CsvView.csproj b/CsvView.csproj index 50dc404..cebb460 100644 --- a/CsvView.csproj +++ b/CsvView.csproj @@ -64,6 +64,7 @@ + Component diff --git a/FrmCsvViewer.Designer.cs b/FrmCsvViewer.Designer.cs index fff2f13..fd68fc9 100644 --- a/FrmCsvViewer.Designer.cs +++ b/FrmCsvViewer.Designer.cs @@ -51,20 +51,18 @@ // this.txtPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtPath.Location = new System.Drawing.Point(7, 27); - this.txtPath.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtPath.Location = new System.Drawing.Point(5, 18); this.txtPath.Name = "txtPath"; - this.txtPath.Size = new System.Drawing.Size(676, 26); + this.txtPath.Size = new System.Drawing.Size(452, 20); this.txtPath.TabIndex = 0; this.txtPath.DoubleClick += new System.EventHandler(this.txtPath_DoubleClick); // // btnLoad // this.btnLoad.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnLoad.Location = new System.Drawing.Point(691, 27); - this.btnLoad.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnLoad.Location = new System.Drawing.Point(461, 18); this.btnLoad.Name = "btnLoad"; - this.btnLoad.Size = new System.Drawing.Size(68, 26); + this.btnLoad.Size = new System.Drawing.Size(45, 20); this.btnLoad.TabIndex = 3; this.btnLoad.Text = "Load"; this.btnLoad.UseVisualStyleBackColor = true; @@ -76,9 +74,11 @@ | System.Windows.Forms.AnchorStyles.Right))); this.grpFile.Controls.Add(this.btnLoad); this.grpFile.Controls.Add(this.txtPath); - this.grpFile.Location = new System.Drawing.Point(20, 12); + this.grpFile.Location = new System.Drawing.Point(13, 8); + this.grpFile.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); this.grpFile.Name = "grpFile"; - this.grpFile.Size = new System.Drawing.Size(766, 67); + this.grpFile.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.grpFile.Size = new System.Drawing.Size(511, 44); this.grpFile.TabIndex = 12; this.grpFile.TabStop = false; this.grpFile.Text = "File"; @@ -91,9 +91,10 @@ this.pnlScrollData.AutoScroll = true; this.pnlScrollData.Controls.Add(this.pnlData); this.pnlScrollData.DisableAutoScroll = true; - this.pnlScrollData.Location = new System.Drawing.Point(20, 126); + this.pnlScrollData.Location = new System.Drawing.Point(13, 85); + this.pnlScrollData.Margin = new System.Windows.Forms.Padding(2); this.pnlScrollData.Name = "pnlScrollData"; - this.pnlScrollData.Size = new System.Drawing.Size(766, 664); + this.pnlScrollData.Size = new System.Drawing.Size(511, 429); this.pnlScrollData.TabIndex = 12; // // pnlData @@ -102,10 +103,9 @@ | System.Windows.Forms.AnchorStyles.Right))); this.pnlData.BackColor = System.Drawing.SystemColors.Control; this.pnlData.DisableAutoScroll = true; - this.pnlData.Location = new System.Drawing.Point(0, 0); - this.pnlData.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.pnlData.Location = new System.Drawing.Point(0, 1); this.pnlData.Name = "pnlData"; - this.pnlData.Size = new System.Drawing.Size(766, 80); + this.pnlData.Size = new System.Drawing.Size(511, 51); this.pnlData.TabIndex = 11; // // pnlReg @@ -120,19 +120,17 @@ this.pnlReg.Controls.Add(this.btnLastReg); this.pnlReg.Controls.Add(this.btnNextReg); this.pnlReg.Enabled = false; - this.pnlReg.Location = new System.Drawing.Point(21, 87); - this.pnlReg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.pnlReg.Location = new System.Drawing.Point(14, 57); this.pnlReg.Name = "pnlReg"; - this.pnlReg.Size = new System.Drawing.Size(765, 701); + this.pnlReg.Size = new System.Drawing.Size(510, 456); this.pnlReg.TabIndex = 11; // // btnPrevReg // this.btnPrevReg.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnPrevReg.Location = new System.Drawing.Point(62, 0); - this.btnPrevReg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnPrevReg.Location = new System.Drawing.Point(41, 0); this.btnPrevReg.Name = "btnPrevReg"; - this.btnPrevReg.Size = new System.Drawing.Size(54, 31); + this.btnPrevReg.Size = new System.Drawing.Size(36, 23); this.btnPrevReg.TabIndex = 5; this.btnPrevReg.Text = "<"; this.btnPrevReg.UseVisualStyleBackColor = true; @@ -147,22 +145,20 @@ this.tblRegNumbers.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tblRegNumbers.Controls.Add(this.txtCurrentReg, 0, 0); this.tblRegNumbers.Controls.Add(this.txtTotalRegs, 1, 0); - this.tblRegNumbers.Location = new System.Drawing.Point(124, 0); - this.tblRegNumbers.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.tblRegNumbers.Location = new System.Drawing.Point(83, 0); this.tblRegNumbers.Name = "tblRegNumbers"; this.tblRegNumbers.RowCount = 1; this.tblRegNumbers.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tblRegNumbers.Size = new System.Drawing.Size(517, 31); + this.tblRegNumbers.Size = new System.Drawing.Size(345, 28); this.tblRegNumbers.TabIndex = 10; // // txtCurrentReg // this.txtCurrentReg.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtCurrentReg.Location = new System.Drawing.Point(4, 5); - this.txtCurrentReg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtCurrentReg.Location = new System.Drawing.Point(3, 3); this.txtCurrentReg.Name = "txtCurrentReg"; - this.txtCurrentReg.Size = new System.Drawing.Size(250, 26); + this.txtCurrentReg.Size = new System.Drawing.Size(166, 20); this.txtCurrentReg.TabIndex = 8; this.txtCurrentReg.TextChanged += new System.EventHandler(this.txtCurrentReg_TextChanged); // @@ -170,20 +166,18 @@ // this.txtTotalRegs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtTotalRegs.Location = new System.Drawing.Point(262, 5); - this.txtTotalRegs.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtTotalRegs.Location = new System.Drawing.Point(175, 3); this.txtTotalRegs.Name = "txtTotalRegs"; this.txtTotalRegs.ReadOnly = true; - this.txtTotalRegs.Size = new System.Drawing.Size(251, 26); + this.txtTotalRegs.Size = new System.Drawing.Size(167, 20); this.txtTotalRegs.TabIndex = 9; // // btnFirstReg // this.btnFirstReg.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.btnFirstReg.Location = new System.Drawing.Point(0, 0); - this.btnFirstReg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btnFirstReg.Name = "btnFirstReg"; - this.btnFirstReg.Size = new System.Drawing.Size(54, 31); + this.btnFirstReg.Size = new System.Drawing.Size(36, 23); this.btnFirstReg.TabIndex = 4; this.btnFirstReg.Text = "|<"; this.btnFirstReg.UseVisualStyleBackColor = true; @@ -193,10 +187,9 @@ // this.btnLastReg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.btnLastReg.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnLastReg.Location = new System.Drawing.Point(711, 0); - this.btnLastReg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnLastReg.Location = new System.Drawing.Point(474, 0); this.btnLastReg.Name = "btnLastReg"; - this.btnLastReg.Size = new System.Drawing.Size(54, 31); + this.btnLastReg.Size = new System.Drawing.Size(36, 23); this.btnLastReg.TabIndex = 7; this.btnLastReg.Text = ">|"; this.btnLastReg.UseVisualStyleBackColor = true; @@ -206,10 +199,9 @@ // this.btnNextReg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.btnNextReg.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnNextReg.Location = new System.Drawing.Point(649, 0); - this.btnNextReg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnNextReg.Location = new System.Drawing.Point(433, 0); this.btnNextReg.Name = "btnNextReg"; - this.btnNextReg.Size = new System.Drawing.Size(54, 31); + this.btnNextReg.Size = new System.Drawing.Size(36, 23); this.btnNextReg.TabIndex = 6; this.btnNextReg.Text = ">"; this.btnNextReg.UseVisualStyleBackColor = true; @@ -217,13 +209,12 @@ // // FrmCsvViewer // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(798, 802); + this.ClientSize = new System.Drawing.Size(532, 521); this.Controls.Add(this.pnlScrollData); this.Controls.Add(this.grpFile); this.Controls.Add(this.pnlReg); - this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.Name = "FrmCsvViewer"; this.Text = "CsvViewer"; this.grpFile.ResumeLayout(false); diff --git a/FrmCsvViewer.cs b/FrmCsvViewer.cs index 5c95b7f..a59d7ed 100644 --- a/FrmCsvViewer.cs +++ b/FrmCsvViewer.cs @@ -11,7 +11,7 @@ namespace CsvView { InitializeComponent(); } - + private void txtPath_DoubleClick(object sender, EventArgs e) { OpenFileDialog loadDialog = new OpenFileDialog(); @@ -49,72 +49,15 @@ namespace CsvView { _loadedFile = fileName; txtPath.Text = fileName; - DateTime dtFile = File.GetCreationTime(_loadedFile); - string indexFile = _loadedFile + ".idx"; - if (File.Exists(indexFile) && File.GetCreationTime(indexFile) > dtFile) - { - List tempIndex = Index_LoadFile(indexFile); - _index = tempIndex; - _totalRegs = _index.Count - 1; - } - else - { - // Generate index - DateTime dtNow = DateTime.UtcNow; - var csvParser = new CsvParser(); - csvParser.GenerateIndex(_loadedFile); - TimeSpan tsGenIndex = DateTime.UtcNow - dtNow; + var csvIndexer = new CsvIndexer(); + csvIndexer.LoadIndexOfFile(_loadedFile); + _index = csvIndexer.Index; + _totalRegs = _index.Count - 1; - _index = csvParser.Index; - _totalRegs = _index.Count - 1; - - // Save Index if expensive generation - if (tsGenIndex.TotalSeconds > 2) - { - Index_SaveFile(indexFile); - } - - } RenderReg(0); } - private void Index_SaveFile(string indexFile) - { - if (File.Exists(indexFile)) - { - File.Delete(indexFile); - } - Stream streamOut = File.Open(indexFile, FileMode.Create); - using (BinaryWriter binWriter = new BinaryWriter(streamOut)) - { - binWriter.Write(_index.Count); - for (int i = 0; i < _index.Count; i++) - { - binWriter.Write(_index[i]); - } - } - streamOut.Close(); - } - - private static List Index_LoadFile(string indexFile) - { - var tempIndex = new List(); - - Stream streamIn = File.Open(indexFile, FileMode.Open); - using (BinaryReader binReader = new BinaryReader(streamIn)) - { - int numRegs = binReader.ReadInt32(); - for (int i = 0; i < numRegs; i++) - { - long value = binReader.ReadInt64(); - tempIndex.Add(value); - } - } - streamIn.Close(); - return tempIndex; - } - private List Index_LoadReg(int idx) { var csvParser = new CsvParser(); @@ -150,7 +93,7 @@ namespace CsvView pnlScrollData.SuspendDrawing(); pnlScrollData.VerticalScroll.Value = 0; pnlData.Height = 10; - + pnlData.Controls.Clear(); _currentReg = currentReg; txtCurrentReg.Text = Convert.ToString(currentReg); @@ -162,7 +105,7 @@ namespace CsvView btnNextReg.Enabled = (last == false); List currentData = Index_LoadReg((int)currentReg); - + int y = 0; const int TexboxPadding = 5; const int PaddingLeft = 0; @@ -213,7 +156,7 @@ namespace CsvView pnlScrollData.SuspendDrawing(); pnlScrollData.VerticalScroll.Value = 0; pnlData.Height = 10; - + pnlData.Controls.Clear(); pnlReg.Enabled = false; txtCurrentReg.Text = string.Empty; @@ -222,7 +165,7 @@ namespace CsvView pnlScrollData.ResumeDrawing(); _rendering = false; } - + private void btnFirstReg_Click(object sender, EventArgs e) { RenderReg(0);