Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Check if file exists and if so append to it, if not create new file 2

Status
Not open for further replies.

DPlank

IS-IT--Management
May 30, 2003
1,903
GB
Hi,

I've a console application which writes to two log files in C:\Temp. These files have the date incorporated to allow a new file for each day. Currently I'm having a problem with using the files.

Each time around I declare a New instance of my class, it calls the fso.CreateTextFile method, passing in the name I want to use. See the code below:

Code:
Public Sub New()
        ' To achieve best speed we use 2 screen iDELAYs.  A longer one for login stage and a shorter one for running stage.
        iLOGIN_iDELAY = 1000
        iRUNNING_iDELAY = 500
        iDELAY = iLOGIN_iDELAY
        Dim dDateVals(3)
        Dim dDateVal
        dDateVal = System.DateTime.Today
        dDateVals = Strings.Split(dDateVal, "/")
        dDateVal = dDateVals(0) & dDateVals(1) & dDateVals(2)
        Dim sFileName As String = "c:\temp\scms_log" & dDateVal & ".txt"
        Dim sScreenFile As String = "c:\temp\scms_screen_log" & dDateVal & ".txt"
        Dim bFoundLog = False
        Dim bFoundScreen = False
        

        oFSO = CreateObject("scripting.filesystemobject")

        bFoundLog = FindFiles(sFileName)
        bFoundScreen = FindFiles(sScreenFile)

        If bFoundLog = False then
            oLOGFILE = oFSO.CreateTextFile(sFileName)
            oSCREENLOG = oFSO.CreateTextFile(sScreenFile)
        End If

        oEXTRA = CreateObject("EXTRA.System")
        oSESSIONS = oEXTRA.Sessions
        'Set oSESSION = oSESSIONS.Open("C:\Program Files\E!PC\Sessions\BACKDCMS.EDP")

        If oSESSIONS.Count > 0 Then
            oSESSION = oEXTRA.ActiveSession
            oSCREEN = oSESSION.Screen
        End If

    End Sub
    Public Function FindFile(ByVal sFileName)
        Dim oFile As Object

        oFile = CreateObject("Microsoft.VisualBasic.FileIO.FileSystem")

        If oFile.FileExists(sFileName) Then
            'found
            FindFile = True
        Else
            'not found
            FindFile = False
        End If

    End Function

I get an exception in the FindFiles function which says it can't create ActiveX objects. Not sure why this is?

With this in mind I changed the code with the understanding that each time I created my new instance of the class, if the file already existed, the overwrite parameter of CreateTextFile would default to false, meaning it wouldn't create a new file, but (I hoped) append to the existing one. Unfortunately it does create a new file.

The oLOGFILE and oSCREENLOG are both closed prior to any call to the class's New sub. The Help seems to indicate that what I thought about the overwrite is correct, but it's clearly not?


Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
Take a look at the System.IO.File class. I think it will make your life much easier :-D

Hpe this helps,

Alex

[small]----signature below----[/small]
Majority rule don't work in mental institutions

My Crummy Web Page
 
Thanks Alex, had a look but being advised that this line:
Code:
oFSO = CreateObject("System.IO.File")

cannot create an ActiveX object. I should advise I'm rather new to this whole process, being a Tester by trade rather than a developer...

Any further suggestions?

Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
Don't create an oject. At the top of your code Add
Code:
Import System.IO

Then if you want to check a file
Code:
If File.Exists(filename) = True then
    'Do true
else
    'Do something else
End If

I don't get what some of your code is doing so I can't help more that that.

-I hate Microsoft!
-Forever and always forward.
 
Thanks for the assist Sorwen. Code now looks like:
Code:
Public Sub New()
        ' To achieve best speed we use 2 screen iDELAYs.  A longer one for login stage and a shorter one for running stage.
        iLOGIN_iDELAY = 1000
        iRUNNING_iDELAY = 500
        iDELAY = iLOGIN_iDELAY
        Dim dDateVals(3)
        Dim dDateVal
        dDateVal = System.DateTime.Today
        dDateVals = Strings.Split(dDateVal, "/")
        dDateVal = dDateVals(0) & dDateVals(1) & dDateVals(2)
        Dim sFileName As String = "c:\temp\scms_log" & dDateVal & ".txt"
        Dim sScreenFile As String = "c:\temp\scms_screen_log" & dDateVal & ".txt"
        

        oFSO = CreateObject("scripting.filesystemobject")

        If File.Exists(sFileName) = True Then
            ' assign file to oLOGFILE and oSCREENLOG

        Else
            ' create and assign file to oLOGFILE and oSCREENLOG
            oLOGFILE = oFSO.CreateTextFile(sFileName)
            oSCREENLOG = oFSO.CreateTextFile(sScreenFile)

        End If

        oEXTRA = CreateObject("EXTRA.System")
        oSESSIONS = oEXTRA.Sessions
        

        If oSESSIONS.Count > 0 Then
            oSESSION = oEXTRA.ActiveSession
            oSCREEN = oSESSION.Screen
        End If

    End Sub

Sorwen, I'm trying to achieve one of two outcomes. If the filename specified doesn't exist, I'll create a new one and assign it to oLOGFILE and oSCREENLOG. If the file does already exist, I want to assign those objects to the existing files and open them so I can append further logging statements to the files.

Hmm. Confusing myself slightly with that explanation, but that's it in a nutshell.
Thanks for your help!


Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
To add to Sorwen's assistance, you also want to look at the System.IO.Streamwriter class. There is a parameter in this class that will automatically append to a file if it exists and create a new one if not....all in one line of code for you. [smile]

Code:
Using sw As New StreamWriter(FileName, True)
    ' You code to write here
    ' sw.WriteLine("text")
    sw.Close 'Close and save the file
End Using

=======================================
People think it must be fun to be a super genius, but they don't realize how hard it is to put up with all the idiots in the world. (Calvin from Calvin And Hobbs)

Robert L. Johnson III
CCNA, CCDA, MCSA, CNA, Net+, A+, CHDP
VB/Access Programmer
 
It is just annoying me so I'll ignore the part I don't get. It really seems there is a lot of code missing so I can't say these changes are the best, but off what you posted this is what I would do.

Code:
Imports System.IO

Public Sub New()
        ' To achieve best speed we use 2 screen iDELAYs.  A longer one for login stage and a shorter one for running stage.
        iLOGIN_iDELAY = 1000
        iRUNNING_iDELAY = 500
        iDELAY = iLOGIN_iDELAY
        Dim dDateVals As String = Now.Month & Now.Day & Now.Year
        Dim sFileName As String = "c:\temp\scms_log" & dDateVal & ".txt"
        Dim sScreenFile As String = "c:\temp\scms_screen_log" & dDateVal & ".txt"    

        If File.Exists(sFileName) = False then
            File.Create(sFileName)
        End If

        If File.Exists(sScreenFile) = False then
            File.Create(sScreenFile)
        End If

        oEXTRA = CreateObject("EXTRA.System")
        oSESSIONS = oEXTRA.Sessions
        'Set oSESSION = oSESSIONS.Open("C:\Program Files\E!PC\Sessions\BACKDCMS.EDP")

        If oSESSIONS.Count > 0 Then
            oSESSION = oEXTRA.ActiveSession
            oSCREEN = oSESSION.Screen
        End If

    End Sub

No clue why you wanted to split the date up like that (used else where in the code as well, but I would suggest some form of change like I did (you can use Now or Today to pull the info I just tend to use now). You returned a check for both files, but before you created you only check if one was made. Not sure why so splitted into two different IF. Also you don't write anything to the files, but assume you do some where you want to look at creating a StreamWriter.

-I hate Microsoft!
-Forever and always forward.
 
Thanks for your help thus far guys. Sorwen, you're correct that these log files are written to in other places - every function within the class uses these files for output.

To answer your questions - I used this method of splitting up the date as it was the only one I knew (very new to this) and I only checked on the one file because if one of them wasn't present, neither would be.

As you can see from the function definition it is the New initialisation of an instance of the class. This is called as part of a looping service running on a host machine which watches a workqueue, picks up work, processes it and returns to the start. Each time we restart, I create a new instance of the class to work with.

Each time we run through I want to check if files with today's date exist, and if so, append the text from this run through to the existing files. If they do not exist then I need to create files with todays date, then assign them to the oLOGFILE and oSCREENLOG objects so I have somewhere for the functions to report to.

From the help given so far, I can check if the files exist and if they do not, I can create them and assign them to the relevant objects. However I'm stuck on the process of setting the objects if the files do already exist.


Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
I'm uncertain if this will work or not, but I'll give it a shot.

Previously (although not shown) the oLOGFILE and oSCREENLOG objects had their Close method invoked at the end of the main loop, freeing the objects prior to creating the new instance of the class.

With a little lateral thinking, I've removed the Close statements from where they were and placed them in the New function as below:
Code:
Public Sub New()
        ' To achieve best speed we use 2 screen iDELAYs.  A longer one for login stage and a shorter one for running stage.
        iLOGIN_iDELAY = 1000
        iRUNNING_iDELAY = 500
        iDELAY = iLOGIN_iDELAY
        Dim dDateVal

        dDateVal = Now.Day & Now.Month & Now.Year
        Dim sFileName As String = "c:\temp\scms_log" & dDateVal & ".txt"
        Dim sScreenFile As String = "c:\temp\scms_screen_log" & dDateVal & ".txt"
        

        oFSO = CreateObject("scripting.filesystemobject")

        If File.Exists(sFileName) = False Then
            If Not oLOGFILE Is Nothing Then
                ' Close off and release the file objects
                oLOGFILE.Close()
                oSCREENLOG.Close()
            End If
            ' Close off and release the file objects
            oLOGFILE.Close()
            oSCREENLOG.Close()
            ' create and assign file to oLOGFILE and oSCREENLOG
            oLOGFILE = oFSO.CreateTextFile(sFileName)
            oSCREENLOG = oFSO.CreateTextFile(sScreenFile)
        End If

        oEXTRA = CreateObject("EXTRA.System")
        oSESSIONS = oEXTRA.Sessions

        If oSESSIONS.Count > 0 Then
            oSESSION = oEXTRA.ActiveSession
            oSCREEN = oSESSION.Screen
        End If

    End Sub

By my reckoning, (which may well turn out to be wrong) the first time we run through this in a day we will see the False outcome from the File.Exists, and we will therefore create the text files. Subsequently, the outcome will be True (as the files will exist) and the code will skip over this stage avoiding the Close statements and allowing the existing files to continue being used until the filename isn't found as a result of the day changing.

At which point (I think) we'll create new files just fine and process with those from that point. I've added the part about if Not ..is Nothing to ensure on the first run we don't hit a problem with the Close statements as they won't execute unless oLOGFILE has already been assigned, which in every case after the first will be true.

Anyone see any flaws in my thinking?



Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
NOTE: I was right this up when you posted so that is why nothing is said till mid way.

The way things are done (vb.net 2005) you don't because you really want to read with a StreamReader and write with a StreamWriter. Each (as far as I've seen) locks the file while in use. Also because a StreamWriter will create a file if it doesn't exist as long as you use the append true flag like mstrmage1768 showed it doesn't really matter. You would only really want to check before you went to read the file in your program.

All that said if your program never reads the log file then, while I don't really recommend it, you could just pass around the StreamReader. It really doesn't save you anything though. As an example off what you posted and I changed before.

Code:
Imports System.IO

Dim swFileName As StreamWriter
Dim sScreenFile As StreamWriter

Public Sub New()
        ' To achieve best speed we use 2 screen iDELAYs.  A longer one for login stage and a shorter one for running stage.
        iLOGIN_iDELAY = 1000
        iRUNNING_iDELAY = 500
        iDELAY = iLOGIN_iDELAY
        Dim dDateVals As String = Now.Month & Now.Day & Now.Year
        Dim sFileName As String = "c:\temp\scms_log" & dDateVal & ".txt"
        Dim sScreenFile As String = "c:\temp\scms_screen_log" & dDateVal & ".txt"    

        If File.Exists(sFileName) = False then
            File.Create(sFileName)
            swFileName = New StreamWriter(sFileName, True)
        End If

        If File.Exists(sScreenFile) = False then
            File.Create(sScreenFile)
            swScreenFile = New StreamWriter(sScreenFile, True)
        End If

        oEXTRA = CreateObject("EXTRA.System")
        oSESSIONS = oEXTRA.Sessions
        'Set oSESSION = oSESSIONS.Open("C:\Program Files\E!PC\Sessions\BACKDCMS.EDP")

        If oSESSIONS.Count > 0 Then
            oSESSION = oEXTRA.ActiveSession
            oSCREEN = oSESSION.Screen
        End If

    End Sub

Then when ever you wanted to write a line to the file you would just sFileName.WriteLine(varText). Really though since this is a class, and you create an instance for the class, it would be better to just to have the class keep track of the file name and then put the writer in a function that could be called whenever. Also since you instance the class there is no reason to close the object " oLOGFILE.Close()" before trying to use it since it will never exist when you make a new class. The only way you would need that is if you didn't instance the class.

Code:
Imports System.IO

Dim sFileName As String
Dim sScreenFile As String

    Public Sub New()
        ' To achieve best speed we use 2 screen iDELAYs.  A longer one for login stage and a shorter one for running stage.
        iLOGIN_iDELAY = 1000
        iRUNNING_iDELAY = 500
        iDELAY = iLOGIN_iDELAY
        Dim dDateVals As String = Now.Month & Now.Day & Now.Year
        sFileName = "c:\temp\scms_log" & dDateVal & ".txt"
        sScreenFile = "c:\temp\scms_screen_log" & dDateVal & ".txt"    

        oEXTRA = CreateObject("EXTRA.System")
        oSESSIONS = oEXTRA.Sessions
        'Set oSESSION = oSESSIONS.Open("C:\Program Files\E!PC\Sessions\BACKDCMS.EDP")

        If oSESSIONS.Count > 0 Then
            oSESSION = oEXTRA.ActiveSession
            oSCREEN = oSESSION.Screen
        End If

    End Sub

    Public Function WriteLogs(ByVal text As String)
        Using sw As New StreamWriter(FileName, True)
            ' You code to write here
            ' sw.WriteLine("text")
            sw.Close 'Close and save the file
        End Using
    End Sub

Also notice how I put the file names outside of the New. The reason is if you have code outside of the new that uses that file information you have to declare it for the whole class. So from what you said your above code would have to change as well or your objects would not be available for other functions.

-I hate Microsoft!
-Forever and always forward.
 
oops I got so caught up I didn't watch what I created. Need these changes for the function. Also not knowing if the logs have the same text you would I made two different write functions.

Code:
    Public Function WriteFileName(ByVal text As String)
        Dim swFileName As New StreamWriter(sFileName, True)
        swFileName.WriteLine(text)
        swFileName.Close
    End Sub

    Public Function WriteScreenFile(ByVal text As String)
        Dim swScreenFile As New StreamWriter(sFileName, True)
        swScreenFile .WriteLine(text)
        swScreenFile .Close
    End Sub

Or of course write one and pass info saying which file to write to.

-I hate Microsoft!
-Forever and always forward.
 
Thanks again Sorwen.

Can I just check that in your WriteLogs function, in order to pass in the file required, I'd need to add it to the Function declaration like so:

Public Function WriteLogs(ByVal text As String, ByVal FileName as string)

Or was there something I'm missing about this?

Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
Cross posting again! I've taken the single function, pass the filename route.

Thanks for your help!

Cheers,
Dave

"Yes, I'll stop finding bugs in the software - as soon as you stop writing bugs into the software." <-- Me

For all your testing needs: Forum1393
 
Yep, Yep. NP.

-I hate Microsoft!
-Forever and always forward.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top