Using StreamReader to determine if File has been changed - vb.net

I am curious. If I am using a combination of streamreader and streamwriter is there a way that I can have a stream written only if File X has been modified?
This code may not be constructed in the best way. It is attached to help in getting my questions accross.
sCommand = "whoami.exe >> C:\Desktop\Test.txt"
Using swrr As New StreamWriter(File.Open(ErrorLog, FileMode.OpenOrCreate))
For Each strUserName As String In strLines
Shell("cmd.exe /c" & sCommand, AppWinStyle.Hide, True, )
'command Cannot Execute, List Why and Move onto Next Command
Using sr As New StreamReader(File.Open(Test.txt, FileMode.OpenOrCreate))
If '''??File has been modifed??''''' Then swrr.WriteLine("PASS") Else swrr.WriteLine("FAIL")
End Using
Next
End Using

You can call File.ReadAllText(path) to get a string containing the text.
You can then compare the new string to the old one.
The correct way to read the output of a command is to use the Process class with RedirectStandardOutput.
You can then create a StreamReader around StandardOutput and call ReadToEnd().

Related

Reading two lines from StreamReader VB.Net

I have a problem reading two lines from a stream reader. I want to read the first line and then proceed to the next one. Here's my code:
Public Function Read()
Dim a As New MemoryStream(ASCII.GetBytes("[ID] " & vbCrLf & " salut" & vbCrLf))
Debug.Print(client.ReadLine(a))
Debug.Print(client.ReadLine(a))
End Function
Public Function ReadLine(ByVal Data As MemoryStream)
Dim sr As New StreamReader(Data)
Return sr.ReadLine
End Function
The output is:
[ID]
One line. I checked the stream in debug mod and I've seen that the position was 15 after the first ReadLine call. So I have to move the "pointer" after the first VbCrLf(that's all the way to the end). But I don't think that's the proper way of doing it. Where am I wrong? I even passed the stream by value so it should've worked.
EDIT
I made some checks and it seems that and only when passing a stream the position moves to the end. I created a stream reader in the same Read function and passed as parameter the a memory stream. It worked. I don't know why this happen. I'm still looking for an answear.
It is not clear what you are really trying to do, but you are not really trying to read two lines from [a] StreamReader, you are trying to read one line at a time from two different streamreaders using the same data source/buffer.
Dim buff = Encoding.ASCII.GetBytes("[ID] " & vbCrLf & " salut" & vbCrLf)
Using ms As New MemoryStream(buff)
Using sr As New StreamReader(ms)
Console.WriteLine(sr.ReadLine())
Console.WriteLine("memstream poition: " & ms.Position)
Console.WriteLine(sr.ReadLine())
Console.WriteLine("memstream poition: " & ms.Position)
Console.WriteLine(sr.ReadLine())
End Using
End Using
If you set a breakpoint on the first sr.ReadLine(), you'll see that the MemoryStream position has changed. If you mouse over the srvariable, you'll see why:
Streamreader has a buffer, 1024 bytes by default. You can compare that buffer to the one created in code and see they are the same. There is also a StreamReader overload which allows you to specify the size:
Public Sub New(stream As System.IO.Stream,
encoding As System.Text.Encoding,
detectEncodingFromByteOrderMarks As Boolean,
bufferSize As Integer)
Trying to read from a single data stream with different (new) StreamReaders wont work because the previous one will have already consumed some of the data. You should be able to read many thousands of lines into an array or list which your code can use as a line-buffer.

How to download file from SFTP in vb.net

I am trying to use the classes in Renci.SshNet.Sftp to download a file from an SFTP server with VB.NET. Here is my code:
Using client As New SftpClient("server", "test", "test")
client.Connect()
Dim list As List(Of SftpFile) = CType(client.ListDirectory(""), List(Of SftpFile))
'------------------------
For Each sFile As SftpFile In list
Console.WriteLine(sFile.Name)
client.DownloadFile("path", ????)
Next
client.Disconnect()
End Using
With this code I can connect to the server and see the file, but I can't download it. I don't know how to call the DownloadFile method.
The second parameter of the DownloadFile method takes a stream. So, you just need to create a new FileStream to write the downloaded data to a new file, like this:
Using fs As New FileStream(localFilePath, FileMode.CreateNew, FileAccess.Write)
client.DownloadFile(serverFilePath, fs)
End Using

Getting DNS Cache in vb.net and returning domains

What's the best way to get the DNS Cache in Visual Basic and returning recently resolved domains? I only need the domains to compare them whit a list.
Function GetDnsCache()
Dim DNSCache As New Process
DNSCache.StartInfo.FileName = "ipconfig"
DNSCache.StartInfo.Arguments = "/displaydns "
DNSCache.StartInfo.UseShellExecute = False
DNSCache.StartInfo.RedirectStandardOutput = True
DNSCache.
DNSCache.Start()
MsgBox(DNSCache.StandardOutput.ReadToEnd())
DNSCache.WaitForExit()
End Function
This is not the cleanest way of doing this and it also takes ages to parse and load.
I would do something like this. It executes ipconfig /displaydns and appends the output to a file. Then, the file is read line by line and displayed wherever you want (I've used a Listbox)
Dim Shell = CreateObject("Wscript.Shell")
Shell.run("cmd /c ipconfig /displaydns >> C:\ipconfig.txt")
Using reader As New IO.StreamReader("C:\ipconfig.txt")
While Not reader.EndOfStream
Dim currentLine As String = reader.ReadLine()
ListBox1.Items.Add(currentLine)
End While
End Using
Should you like to display the info into a MsgBox...
Dim Shell = CreateObject("Wscript.Shell")
Shell.run("cmd /c ipconfig /displaydns >> C:\ipconfig.txt")
Dim reader as As New IO.StreamReader("C:\ipconfig.txt")
MsgBox(reader.ReadToEnd.ToString, MsgBoxStyle.Information)

Writeline overwriting the last line

I am trying to writeline into a text file this works accept it appears to overwrite the last line each time. I would like it to write to the next line instead of overwriting. Here is the code I'm using
Dim FileNumber As Integer = FreeFile()
FileOpen(FileNumber, "c:\Converted.txt", OpenMode.Output)
PrintLine(FileNumber, convertedDir)
FileClose(FileNumber)
You are using an old (VB6/VBA) code, better use the .NET StreamWriter:
Dim append As Boolean = True
Using writer As System.IO.StreamWriter = New System.IO.StreamWriter("c:\Converted.txt", append)
writer.WriteLine(convertedDir)
End Using
append indicates whether the given file should be appended. Nonetheless, as suggested by Boris B., you can set this variable always to True because StreamWriter is capable to deal with both situations (existing file or not) automatically.
In any case, I am including below the "theoretically right" way to deal with StreamWriter (by changing the append property depending upon the fact that the given file is present or not):
Dim append As Boolean = False
Dim fileName As String = "c:\Converted.txt"
If (System.IO.File.Exists(fileName)) Then
append = True
End If
Using writer As System.IO.StreamWriter = New System.IO.StreamWriter(fileName, append)
writer.WriteLine(convertedDir) 'Writes to a new line
End Using
For a quick solution based on existing code change the line
FileOpen(FileNumber, "c:\Converted.txt", OpenMode.Output)
to
FileOpen(FileNumber, "c:\Converted.txt", OpenMode.Append)
However, you should really update your method of writing files, since FileOpen and similar are there just for compatibility with older VB & VBA programs (and programmers :). For a more modern solution check out varocarbas' answer.

Stream Reader and Writer Conflict

I am making a class that is to help with saving some strings to a local text file (I want to append them to that file and not overwrite so that it is a log file). When I write with the streamwriter to find the end of the previous text, I get an error "the file is not available as it is being used by another process". I looked into this problem on MSDN and I got very little help. I tried to eliminate some variables so I removed the streamreader to check was that the problem and it was. When I tried to write to the file then it worked and I got no error so this made me come to the conclusion that the problem arose in the streamreader. But I could not figure out why?
Here is the code:
Public Sub SaveFile(ByVal Task As String, ByVal Difficulty As Integer, ByVal Time_Taken As String)
Dim SW As String = "C:/Program Files/Business Elements/Dashboard System Files/UserWorkEthic.txt"
Dim i As Integer
Dim aryText(3) As String
aryText(0) = Task
aryText(1) = Difficulty
aryText(2) = Time_Taken
Dim objWriter As System.IO.StreamWriter = New System.IO.StreamWriter(SW, True)
Dim reader As System.IO.StreamReader = New System.IO.StreamReader(SW, True)
reader.ReadToEnd()
reader.EndOfStream.ToString()
For i = 0 To 3
objWriter.WriteLine(aryText(reader.EndOfStream + i))
Next
reader.Close()
objWriter.Close()
End Sub
As Joel has commented on the previous answer it is possible to change the type of locking.
Otherwise building on what Neil has suggested, if to try to write to a file with a new reader it is difficult not to lose the information already within the file.
I would suggest you rename the original file to a temporary name, "UserWorkEthicTEMP.txt" for example. Create a new text file with the original name. Now; read a line, write a line, between the two files, before adding your new data onto the end. Finally Delete the temporary file and you will have the new file with the new details. If you have an error the temporary file will serve as a backup of the original. Some sample code below:
Change file names
Dim Line as string
line=Reader.readline
Do until Line=nothing
objwriter.writeline(line)
line=reader.readline
loop
add new values on the end and remove old file
You are trying to read and write to the same file and this is causing a lock contention. Either store the contents of the file into a variable and then write it back out including your new data to the file.
Psuedo
Reader.Open file
String content = Reader.ReadToEnd()
Reader.Close
Writer.Open file
Loop
Writer.Write newContent
Writer.Close