I was wondering if/how you can read a specific line in vb.net using a system.io.streamreader.
Dim streamreader as system.io.streamreader
streamreader.selectline(linenumber as int).read
streamreader.close()
Is this possible or is there a similiar function to this one?
I'd use File.ReadAllLines to read in the lines into an array, then just use the array to select the line.
Dim allLines As String() = File.ReadAllLines(filePath)
Dim lineTwo As String = allLines(1) '0-based index
Note that ReadAllLines will read the entire text file into memory but I assume this isn't a problem because, if it is, then I suggest you take an alternative approach to trying to jump to a specific line.
ReadLines is pretty fast as it doesn't load everything in memory. It returns an IEnumerable<string> which allow you to skip to a line easily. Take this 5GB file:
var data = new string('A', 1022);
using (var writer = new StreamWriter(#"d:\text.txt"))
{
for (int i = 1; i <= 1024 * 1024 * 5; i++)
{
writer.WriteLine("{0} {1}", i, data);
}
}
var watch = Stopwatch.StartNew();
var line = File.ReadLines(#"d:\text.txt").Skip(704320).Take(1).FirstOrDefault();
watch.Stop();
Console.WriteLine("Elapsed time: {0}", watch.Elapsed); // Elapsed time: 00:00:02.0507396
Console.WriteLine(line); // 704320 AAAAAA...
Console.ReadLine();
Related
I need to generate a hash of a file in VB.NET on a server and send it to an AS3 client for validation against a file on the client. I chose MD5. I am using the builtin VB.NET MD5 hash and the hurlant MD5 hash on AS3. The results are different.
I am looking for a moderately reliable method of verifying the files are the same. Speed is as important as accuracy. I am open to other hashing algorithms which are at least as reliable/secure as MD5.
If there is a solution using what I have that would be great. If there is another way which works, that's OK too.
My VB Code looks like;
Dim baFileData() As Byte = File.ReadAllBytes(HttpContext.Current.Server.MapPath(strFilePath))
Dim strFileHash As String = GetHash(baFileData)
Function GetHash(theInputBytes() As Byte) As String
Using hasher As MD5 = MD5.Create() ' create hash object
' Convert to byte array and get hash
Dim dbytes As Byte() =
hasher.ComputeHash(theInputBytes)
' sb to create string from bytes
Dim sBuilder As New StringBuilder()
' convert byte data to hex string
For n As Integer = 0 To dbytes.Length - 1
sBuilder.Append(dbytes(n).ToString("X2"))
Next n
Return sBuilder.ToString()
End Using
End Function
My AS3 code looks like this;
private function getFileMD5Hash(flLocalFile:File):String
{
var strmInFile:FileStream = new FileStream();
strmInFile.open(flLocalFile, FileMode.READ);
var strFileData:String = strmInFile.readUTFBytes(strmInFile.bytesAvailable);
strmInFile.close();
var hash:IHash = Crypto.getHash("md5");
var baFileData:ByteArray = Hex.toArray(Hex.fromString(strFileData));
var baHash:ByteArray = hash.hash(baFileData);
var strFileHash:String = Hex.fromArray(baHash);
return strFileHash;
}
#Organis basically gave me the tools in his comments to solve the problem. My only reason for posting this as an answer is to show what the resulting code looks like.
If Organis posts an answer I will give it a vote.
The VB code remained the same.
The AS3 code changed to;
private function getFileMD5Hash(flLocalFile:File):String
{
var strmInFile:FileStream = new FileStream();
strmInFile.open(flLocalFile, FileMode.READ);
var baFileData:ByteArray = new ByteArray;
strmInFile.readBytes(baFileData);
strmInFile.close();
var hash:IHash = Crypto.getHash("md5");
var baHash:ByteArray = hash.hash(baFileData);
var strFileHash:String = Hex.fromArray(baHash).toUpperCase();
return strFileHash;
}
I'm trying to save tables from excel sheets as pictures. Is there a way to just put that table on the clipboard and save it? This is what I've got so far but the library referenced is not there?
Thank you in advance!
-Rueben Ramirez
Public Sub extract_excelTable(ByRef data_file As String, ByRef app1 As excel.Application, ByRef sheet_name As String)
'defining new app to prevent out of scope open applications
Dim temp_app As excel.Application = app1
Dim workbook As excel.Workbook = temp_app.Workbooks.Open(Path.GetFullPath(data_file))
temp_app.Visible = False
For Each temp_table As excel.DataTable In workbook.Worksheets(sheet_name)
temp_table.Select()
'temp_app.Selection.CopyAsPicture?
Next
End Sub
I'm not going to write any code here, but I will outline a solution for you that will work. Note that this will not reproduce the formatting of the excel document, just simply get the data from it, and put it on an image in the same column/row order as the excel file.
STEP 1:
My solution to this problem would be to read the data from the excel file using an OLEDB connection as outlined in the second example of this post: Reading values from an Excel File
Alternatively, you may need to open the document in excel and re-save it as a CSV if it's too large to fit in your computer's memory. I have some code that reads a CSV into a string list in C# that may help you:
static void Main(string[] args)
{
string Path = "C:/File.csv";
System.IO.StreamReader reader = new System.IO.StreamReader(Path);
//Ignore the header line
reader.ReadLine();
string[] vals;
while (!reader.EndOfStream)
{
ReadText = reader.ReadLine();
vals = SplitLine(ReadText);
//Do some work here
}
}
private static string[] SplitLine(string Line)
{
string[] vals = new string[42];
string Temp = Line;
for (int i = 0; i < 42; i++)
{
if (Temp.Contains(","))
{
if (Temp.Substring(0, Temp.IndexOf(",")).Contains("\""))
{
vals[i] = Temp.Substring(1, Temp.IndexOf("\",", 1) - 1);
Temp = Temp.Substring(Temp.IndexOf("\",", 1) + 2);
}
else {
vals[i] = Temp.Substring(0, Temp.IndexOf(","));
Temp = Temp.Substring(Temp.IndexOf(",") + 1);
}
}
else
{
vals[i] = Temp.Trim();
}
}
return vals;
}
STEP 2:
Create a bitmap object to create an image, then use a for loop to draw all of the data from the excel document onto the image. This post had an example of using the drawstring method to do so: how do i add text to image in c# or vb.net
I'm using a SqlDataReader to retrieve some "SELECT" query from a DBMS.
So far, I read each row one by one in the result set using SqlDataReader.read(), and I process them one by one. When the result set is huge (meaning millions of rows times hundreds of columns), iterating with .read() is very slow. I'm asking: is there a way to do a "block" read from SqlDataReader, meaning that i.e. something like SqlDataReader.read(100) gives me an array of the next 100 rows in the result set?
I thought about doing something like DataTable.Load() to load all the result set in memory, but since the table has a size of several gigabytes, it would't fit in memory.
What would you recommend?
Thanks a lot
Example code:
TdConnection conn;
TdCommand cmd;
TdDataReader reader;
IAsyncResult res;
conn = new TdConnection(#"xxxx;");
conn.Open();
cmd = new TdCommand(q,conn);
res = cmd.BeginExecuteReader();
while (!res.IsCompleted);
reader = cmd.EndExecuteReader(res);
if (reader.HasRows)
{
string sb;
string currentout = "C:\file";
string[] row = new string[reader.FieldCount];
sb = "";
for (int i = 0; i < reader.FieldCount; i++)
row[i] = reader.GetName(i);
sb = String.Concat(sb,String.Join("\t",row),"\r\n");
File.WriteAllText(currentout,sb);
sb = "";
/* With a test query, the following commented "while" takes 5 minutes
/* to iterate over a dataset with 639967 rows x 63 columns (about 300MB)
/* while(reader.Read());
*/
/* With the same test query, the following "while block" takes 6 minutes
/* to iterate over the same dataset AND writing it on a text file
/* I conclude that I/O writing on text file is fast, and .Read() is very slow
*/
while(reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
row[i] = reader.GetValue(i).ToString();
sb = String.Concat(sb,String.Join("\t",row),"\r\n");
if (sb.Length > 100000)
{
File.AppendAllText(currentout,sb);
sb = "";
}
}
File.AppendAllText(currentout,sb);
}
reader.Close();
reader.Dispose();
cmd.Dispose();
conn.Close();
The "Td" components are the Teradata DBMS interface for .NET (but they behave just like "SQL" components).
What's slow here is the quadratic cost of the string concatenation in the loop:
sb = String.Concat(sb,String.Join("\t",row),"\r\n");
Since this is such a glaring perf problem I'm submitting this as an answer since it probably solves your problem.
If your app is slow, profile it to see what is slow.
Unfortunately, ADO.NET is indeed quite CPU heavy when reading data. Nothing you can do about it.
I would like to make a simple code that counts the top three most recurring lines/ text in a txt file then saves that line/ text to another text file (this in turn will be read into AutoCAD’s variable system).
Forgetting the AutoCAD part which I can manage how do I in VB.net save the 3 most recurring lines of text each to its own text file see example below:
Text file to be read reads as follows:
APG
BTR
VTS
VTS
VTS
VTS
BTR
BTR
APG
PNG
The VB.net program would then save the text VTS to mostused.txt BTR to 2ndmostused.txt and APG to 3rdmostused.txt
How can this be best achieved?
Since I'm C# developer, I'll use it:
var dict = new Dictionary<string, int>();
using(var sr = new StreamReader(file))
{
var line = string.Empty;
while ((line = sr.ReadLine()) != null)
{
var words = line.Split(' '); // get the words
foreach(var word in words)
{
if(!dict.Contains(word)) dict.Add(word, 0);
dict[word]++; // count them
}
}
}
var query = from d in dict select d order by d.Value; // now you have it sorted
int counter = 1;
foreach(var pair in query)
{
using(var sw = new StreamWriter("file" + counter + ".txt"))
sw.writer(pair.Key);
}
I want to save content of a RichTextBox to varbinary (= byte array) in XamlPackage format.
I need technicial advise on how to it.
I actually need to know how to convert between FlowDocument to byte array.
Is it even recommended to store it as varbinary, or this is a bad idea?
Update
Code snippet:
///Load
byte[] document = GetDocumentFromDataBase();
RickTextBox tb = new RickTextBox();
TextRange tr = new TextRange(tb.Document.ContentStart, tb.Document.ContentEnd)
tr.Load(--------------------------) //Load from the byte array.
///Save
int maxAllowed = 1024;
byte[] document;
RichTextBox tb = new RichTextBox();
//User entered text and designs in the rich text
TextRange tr = new TextRange(tb.Document.ContentStart, tb.Document.ContentEnd)
tr.Save(--------------------------) //Save to byte array
if (document.Length > maxAllowed)
{
MessageBox.Show((document.Length - maxAllowed) + " Exceeding limit.");
return;
}
SaveToDataBase();
TextRange
I can't find my full example right now, but you can use XamlReader and XamlWriter to get the document into and out of a string. From there, you can use UnicodeEncoding, AsciiEncoding or whatever encoder you want to get it into and out of bytes.
My shorter example for setting the document from a string...
docReader is my flow document reader
private void SetDetails(string detailsString)
{
if (docReader == null)
return;
if (String.IsNullOrEmpty(detailsString))
{
this.docReader.Document = null;
return;
}
using (
StringReader stringReader = new StringReader(detailsString))
{
using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(stringReader))
{
this.docReader.Document = XamlReader.Load(reader) as FlowDocument;
}
}
}