I am trying to copy the contents of an embedded file to a string in Visual Basic using Visual Studio 2013. I already have the resource (Settings.xml) imported and set as an embedded resource. Here is what I have:
Function GetFileContents(ByVal FileName As String) As String
Dim this As [Assembly]
Dim fileStream As IO.Stream
Dim streamReader As IO.StreamReader
Dim strContents As String
this = System.Reflection.Assembly.GetExecutingAssembly
fileStream = this.GetManifestResourceStream(FileName)
streamReader = New IO.StreamReader(fileStream)
strContents = streamReader.ReadToEnd
streamReader.Close()
Return strContents
End Function
When I try to save the contents to a string by using:
Dim contents As String = GetFileContents("Settings.xml")
I get the following error:
An unhandled exception of type 'System.ArgumentNullException' occurred in mscorlib.dll
Additional information: Value cannot be null.
Which occurs at line:
streamReader = New IO.StreamReader(fileStream)
Nothing else I've read has been very helpful, hoping someone here can tell me why I'm getting this. I'm not very good with embedded resources in vb.net.
First check fileStream that its not empty as it seems its contains nothing that's why you are getting a Null exception.
Instead of writing to file test it by using a msgBox to see it its not null.
fileStream is Nothing because no resources were specified during compilation, or because the resource is not visible to GetFileContents.
After fighting the thing for hours, I discovered I wasn't importing the resource correctly. I had to go to Project -> Properties -> Resources and add the resource from existing file there, rather than importing the file from the Solution Explorer. After adding the file correctly, I was able to write the contents to a string by simply using:
Dim myString As String = (My.Resources.Settings)
Ugh, it's always such a simple solution, not sure why I didn't try that first. Hopefully this helps someone else because I saw nothing about this anywhere else I looked.
Related
I can't seem to figure out why I'm getting a compilation error with this code that tries to find the most recently updated file (all CSV files) in a directory, to then pull the last line of the CSV and update a device.
The exception I get is:
Line 3 Character 10 expected end of statement.
Don't worry about the hs.SetDevice, I know that part is correct.
Imports System.IO
Sub Main()
Dim path = System.IO.DirectoryInfo.GetFiles("C:\Users\Ian\Documents\Wifi Sensor Software").OrderByDescending(Function(f) f.LastWriteTime).First()
Dim line = System.IO.File.ReadLines(path).Last()
Dim fields() = line.Split(",".ToCharArray())
Dim fileTemp = fields(2)
hs.SetDeviceValueByRef(124, fileTemp, True)
End Sub
EDIT:
Changed Directory to DirectoryInfo
The original problem was that Directory.GetFiles() returns an array of strings, a string doesn't have a LastWriteTime Property.
This property belongs to the FileInfo base class, FileSystemInfo, the object type returned by DirectoryInfo.GetFiles().
Then, a FileInfo object cannot be passed to File.ReadLines(), this method expects a string, so you need to pass [FileInfo].FullName.
Hard-coding a Path in that manner is not a good thing. Use Environment.GetFolderPath() to get the Path of special folders, as the MyDocuments folder, and Path.Combine() to build a valid path.
Better use the TextFieldParser class to parse a CSV file. It's very simple to use and safe enough.
The worst problem is Option Strict set to Off.
Turn it On in the Project's Properties (Project->Properties->Compile), or in the general options of Visual Studio (Tools->Options->Projects and Solutions->VB Defaults), so it's already set for new Projects.
You can also add it on top of a file, as shown here.
With Option Strict On, you are immediately informed when a mishap of this kind is found in your code, so you can fix it immediately.
With Option Strict Off, some issues that come up at run-time can be very hard to identify and fix. Setting it On to try and fix the problem later is almost useless, since all the mishaps will come up all at once and you'll have a gazillion of error notifications that will hide the issue at hand.
Option Strict On
Imports System.IO
Imports Microsoft.VisualBasic.FileIO
Dim filesPath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments), "Wifi Sensor Software")
Dim mostRecentFile = New DirectoryInfo(filesPath).
GetFiles("*.csv").OrderByDescending(Function(f) f.LastWriteTime).First()
Using tfp As New TextFieldParser(mostRecentFile.FullName)
tfp.TextFieldType = FieldType.Delimited
tfp.SetDelimiters({","})
Dim fileTemp As String = String.Empty
Try
While Not tfp.EndOfData
fileTemp = tfp.ReadFields()(2)
End While
Catch fnfEx As FileNotFoundException
MessageBox.Show($"File not found: {fnfEx.Message}")
Catch exIDX As IndexOutOfRangeException
MessageBox.Show($"Invalid Data format: {exIDX.Message}")
Catch exIO As MalformedLineException
MessageBox.Show($"Invalid Data format at line {exIO.Message}")
End Try
If Not String.IsNullOrEmpty(fileTemp) Then
hs.SetDeviceValueByRef(124, fileTemp, True)
End If
End Using
Does anyone know how to parse a Webclient.DowloadFile to File in VB.Net?
I'm currently using the following Code but I keep getting the errors:
(BC30491) Expression does not produce a value.
(BC30311) Value of Type can not be converted to File
Private Function DepartmentDataDownloader() As String
Dim webClient As New System.Net.WebClient
'I get here the error BC30491
Dim result As File = webClient.DownloadFile("https://intern.hethoutsemeer.nl/index2.php?option=com_webservices&controller=csv&method=hours.board.fetch&key=F2mKaXYGzbjMA4V&element=departments", "intern.hethoutsemeer.nl.1505213278-Departments.csv")
If webClient IsNot Nothing Then
'and here BC30311
Dim result As File = webClient
UploaderFromDownload(webClient)
End If
Return ""
End Function
The DownloadFile method doesn't return a value, because DownloadFile is a Sub. This is the reason why you get the BC30491 error. The second parameter specifies the path of the local file (and the result of the download).
So you can try something like the following:
Dim webClient As New System.Net.WebClient
'after this the file specified on second parameter should exists.
webClient.DownloadFile("https://intern.hethoutsemeer.nl/index2.php?option=com_webservices&controller=csv&method=hours.board.fetch&key=F2mKaXYGzbjMA4V&element=departments", "intern.hethoutsemeer.nl.1505213278-Departments.csv")
If webClient IsNot Nothing Then
'do something with the downloaded file (File.OpenRead(), File.*).
'Dim result As File
UploaderFromDownload(webClient)
End If
You also try to assign the WebClient value to a File variable. This is not possible so you get the BC30311 error.
Hint: You can't create an instance of the File class. The File class provides static methods for the creation, copying, deletion, moving, and opening of a single file, and aids in the creation of FileStream objects.
source: https://learn.microsoft.com/en-us/dotnet/api/system.io.file
I need download a CSV file and then read it. Here is my code:
tickerValue = "goog"
Dim strURL As String = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
Dim strBuffer As String = RequestWebData(strURL)
Using streamReader = New StreamReader(strBuffer)
Using reader = New CsvReader(streamReader)
I keep getting this error: An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll Additional information: Illegal characters in path.
What am I doing wrong?
Additional Info
In another part of my program I use this code and it works fine.
Address = http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=AMEX&render=download
Dim strBuffer As String = Historical_Stock_Prices.RequestWebData(Address)
Using streamReader = New StringReader(strBuffer)
Using reader = New CsvReader(streamReader)
Isn't my second code the same concept as my problem code?
you are giving it, essentially, a web url. somewhere in your code, it does not support the web url. it could be the streamreader. it could be the CsvReader.
what line of code does this point to?
the best bet is to save the file TO DISK, then read from disk.
UPDATE
here is an example to SAVE to disk:
using writer as new StreamWriter("C:\Test.csv")
writer.Write(strBuffer)
writer.Close()
end using
here is an example to READ from disk:
using strReader as new StreamReader("C:\Test.csv")
' this code is presumably how it works for reading into the CsvReader:
using reader as new CsvReader(strReader)
' now do your thing
end using
strReader.Close()
end using
I've nicked some code from msdn to write and read to an xml file to persist my data, but I need a little help with it. I have a dynamic array called darr. As I understand it, I use this code to store it in an xml file:
Dim objStreamWriter As New StreamWriter("C:\temp\test.xml")
Dim x As New XmlSerializer(darr.GetType)
x.Serialize(objStreamWriter, darr)
objStreamWriter.Close()
And this to read it:
Dim objStreamReader As New StreamReader("C:\temp\test.xml")
darr = x.Deserialize(objStreamReader)
objStreamReader.Close()
The thing is, I want the app to read from the file on startup, which means the second block gets called first and if the file doesn't exit yet, it throws an exception. (The first block automatically creates the file if not found.) So two questions:
Is there a way to have the app create the file automatically the first time it runs?
Since the file will be empty... will the code work? If not, is there a workaround? (Okay that's three questions!)
If Not File.Exists("C:\temp\test.xml") Then
' Create the file.
Dim file As System.IO.FileStream
file = System.IO.File.Create("C:\temp\test.xml")
Else
Dim objStreamWriter As New StreamWriter("C:\temp\test.xml")
Dim x As New XmlSerializer(darr.GetType)
x.Serialize(objStreamWriter, darr)
objStreamWriter.Close()
End If
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