Craig Beamson
asked on
VB - ensuring a text file is written to and closed before opening to read from it
I'd like to read the report or text file generated below (3rd from last line) into a textbox:
If I add a final line:
What do I need to do to ensure the file is written to and closed before attempting to read from it?
Dim config As New MarketplaceWebServiceConfig
config.ServiceURL = "https://mws.amazonservices.co.uk"
Dim myClient As New MarketplaceWebServiceClient(AccessKey, SecretKey, ApplicationName, ApplicationVersion, config)
Dim myRequest As New GetReportRequest
myRequest.Merchant = SellerID
myRequest.ReportId = reportId
myRequest.Report = File.Open("C:\\report\" + reportId.ToString + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)
Dim myResponse As New GetReportResponse
myResponse = myClient.GetReport(myRequest)
If I add a final line:
myTextbox.text = File.ReadAllText("C:\\report\" + reportId.ToString + ".txt")
I get "The process cannot access the file "xxx" because it is being used by another process."What do I need to do to ensure the file is written to and closed before attempting to read from it?
Something like this is what I have been looking at for a similar project. Reviews are good and you can just plug it into the router.
https://www.amazon.com/NETGEAR-LTE-Modem-Broadband-Connection/dp/B01N5ASNTE/ref=sr_1_2?ie=UTF8&qid=1510678769&sr=8-2&keywords=cellular+router
https://www.amazon.com/NETGEAR-LTE-Modem-Broadband-Connection/dp/B01N5ASNTE/ref=sr_1_2?ie=UTF8&qid=1510678769&sr=8-2&keywords=cellular+router
Hi,
In your code, make sur that any opened file is properly closed, even if errors happen (check error handlers).
But, if the file is opened by an external process, there isn't much you can do, beside handling and reporting the error, so the user can try again.
Somes might say that you can try to read it again after a little amount of time, but that's running the risk of locking your application forever (what if the file is locked bc of a crash ? Or was never properly closed ?)
In your code, make sur that any opened file is properly closed, even if errors happen (check error handlers).
But, if the file is opened by an external process, there isn't much you can do, beside handling and reporting the error, so the user can try again.
Somes might say that you can try to read it again after a little amount of time, but that's running the risk of locking your application forever (what if the file is locked bc of a crash ? Or was never properly closed ?)
ASKER
Okay, some mixed suggestions there.
Joe: that's a fair point - I've omitted the Try Catch in my sample code for simplicity (I have it in my main code).
However, this part of the code works fine, without error.
It is only the addition of an attempt to read back from the file immediately afterwards that fails.
Your second comment just seemed to be a link to buy a router!
Fabrice: there should be no external process which accesses the file. I agree any open file should be closed. My question is about how I wait for the action of writing to the file to end before closing the file and attempting to read the file back.
I could do a wait/retry loop but is there some other way of waiting for the previous task (writing to the file) to complete before moving on to the next file open / read commands?
Joe: that's a fair point - I've omitted the Try Catch in my sample code for simplicity (I have it in my main code).
However, this part of the code works fine, without error.
It is only the addition of an attempt to read back from the file immediately afterwards that fails.
Your second comment just seemed to be a link to buy a router!
Fabrice: there should be no external process which accesses the file. I agree any open file should be closed. My question is about how I wait for the action of writing to the file to end before closing the file and attempting to read the file back.
I could do a wait/retry loop but is there some other way of waiting for the previous task (writing to the file) to complete before moving on to the next file open / read commands?
Sorry, I had a lot of tabs open and the link was for another post. I deleted it.
Hi Beamson;
This line of code opens the file for read/write and assigns the return a FileStream to myRequest.Report at which point you relinquish control of the open file to the object myRequest. In that object it should close the file when it is finished using it so that calls to read it from other parts of your app does not fail.
This line of code opens the file for read/write and assigns the return a FileStream to myRequest.Report at which point you relinquish control of the open file to the object myRequest. In that object it should close the file when it is finished using it so that calls to read it from other parts of your app does not fail.
myRequest.Report = File.Open("C:\\report\" + reportId.ToString + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)
I assume that after this line of code is executed the myRequest object has completed using the file and should have closed it.
myResponse = myClient.GetReport(myRequest)
ASKER
should have closed it
I agree, the file should be closed but for some reason it is not.
If I debug the sub with a long system.threading value (few minutes) and then try to access the textfile I get the same problem.
If I debug it with no system.threading value, let is fail, then open the same file from another subroutine, it opens fine. It is as though the process that creates and writes to the file is not releasing the file once written to.
If I separate the writing and reading back of the text file into two separate subs and run them in the same debugging session, they also fail with the same error when reading back. I feel as though I need to explicitly release the file somewhere but don't know where or how.
Please post the class myRequest here.
Thanks
Thanks
ASKER
Dim myRequest As New GetReportRequest
myRequest.Merchant = SellerID
myRequest.ReportId = reportId
myRequest.Report = File.Open(MyPath+ reportId.ToString + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)
Imports System
Imports System.IO
Imports System.Xml.Serialization
Imports MarketplaceWebService.Attributes
Namespace MarketplaceWebService.Model
<MarketplaceWebService(RequestType:=RequestType.DEFAULT, ResponseType:=ResponseType.STREAMING)> <XmlRoot([Namespace]:="http://mws.amazonaws.com/doc/2009-01-01/", IsNullable:=False)> <XmlType([Namespace]:="http://mws.amazonaws.com/doc/2009-01-01/")>
Public Class GetReportRequest
Public Sub New()
<Obsolete("Not used anymore. MWS ignores this parameter, but it is left in here for backwards compatibility.")> <XmlElement(ElementName:="Marketplace")>
Public Property Marketplace As String
<XmlElement(ElementName:="Merchant")>
Public Property Merchant As String
<XmlElement(ElementName:="MWSAuthToken")>
Public Property MWSAuthToken As String
<MarketplaceWebServiceStream(StreamType:=StreamType.RECEIVE_STREAM)>
Public Property Report As Stream
<XmlElement(ElementName:="ReportId")>
Public Property ReportId As String
<Obsolete("Not used anymore. MWS ignores this parameter, but it is left in here for backwards compatibility.")>
Public Function IsSetMarketplace() As Boolean
Public Function IsSetMerchant() As Boolean
Public Function IsSetMWSAuthToken() As Boolean
Public Function IsSetReport() As Boolean
Public Function IsSetReportId() As Boolean
<Obsolete("Not used anymore. MWS ignores this parameter, but it is left in here for backwards compatibility.")>
Public Function WithMarketplace(marketplace As String) As GetReportRequest
Public Function WithMerchant(merchant As String) As GetReportRequest
Public Function WithMWSAuthToken(mwsAuthToken As String) As GetReportRequest
Public Function WithReport(report As Stream) As GetReportRequest
Public Function WithReportId(reportId As String) As GetReportRequest
End Class
End Namespace
Where is the implementation for this?
Public Function WithReport(report As Stream) As GetReportRequest
ASKER
Not sure how to answer that question. The classes are provided as part of one of Amazon's dlls. Will take a look tomorrow and see what I can find when I'm at my desk.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That did the trick!
I'd tried variations of that but was focusing on closing the response objects rather than the request ones.
Your way worked immediately.
Thanks for all of your help!
I'd tried variations of that but was focusing on closing the response objects rather than the request ones.
Your way worked immediately.
Thanks for all of your help!
Not a problem Beamson, glad I was able to help.
Open in new window
Since it looks like this is a web app, you should be writing this to the database and then perhaps write another program that pulls the information from the database and writes it to a file. The program can be a console program that gets called from the task scheduler. This will prevent more than one program from accessing files at the same time.