Create/Delete Files? Xojo 2023R4

Hello all,

I’ve always had trouble with GetFolderItem and creating files.

In this case, I know the folder, but want to create an empty file “startup.txt” in that specific folder.
What is the best way to do this?

Thanks,
Tim

Use a TextOutputStream, Create the file, but just don’t write to it.

1 Like

Always make sure you use error handling when you do file IO. Here’s a method that’ll create the empty file, you just pass it a folder and a filename and it returns a boolean indicating whether or not the empty file was successfully created.

Public Function CreateEmptyFile(Folder as FolderItem, Filename as String) As Boolean
  If Folder <> Nil And Folder.Exists Then
    Var newFile As FolderItem = Folder.Child(Filename)
    
    // Check if the file already exists to avoid overwriting it
    If Not newFile.Exists Then
      Try
        Var textStream As TextOutputStream = TextOutputStream.Create(newFile)
        textStream.Close // Close the stream since we're creating an empty file
        
        Return True // File created successfully
      Catch e As IOException
        
        // Error occurred, return False
        Return False
      End Try
    Else
      Return False // File already exists
    End If
  Else
    Return False // Folder not found or can't write to it.
  End If
  
  // In case the folder doesn't exist, or file already exists, return False
  Return False
End Function

Just a note: if the folder exists, and the file also exists but is inaccessible (e.g. ACL rules or other access settings), your code would crash at the quoted line (newFile would be nil). I’d suggest you change to “if not (newFile=nil or newFile.Exists) then”.

1 Like

Good catch! Alternatively, could move the Try up one line.

Thanks guys!

Tim

Or just use exception handling as

Public Sub CreateEmptyFile(fileToCreate as FolderItem)

  If fileToCreate = Nil Then Raise New IOException("Not a valid file", 0)
  
  If fileToCreate.Exists Then Raise New IOException("File already exists", 1)
  
  Call BinaryStream.Create(fileToCreate) // Create and dispose handle
  
End Sub

// Use as:

Try 
  Var f As FolderItem = SpecialFolder.Documents.Child("any bin or txt.png")
  CreateEmptyFile(f)
Catch e
  // Shot happens
  MessageBox("Could not create, reason: " + e.Message)
  Quit // Do what you need here
End

2 Likes

Without extra functions…

Try 
  Var f As FolderItem = SpecialFolder.Documents.Child("any bin or txt.png")
  Call BinaryStream.Create(fileToCreate)
Catch e
  // Shot happens
  MessageBox("Could not create, reason: " + e.Message)
  Quit // Do what you need here
End
1 Like

Thanks for this example, @Rick_Araujo, it’s really concrete and useful. I have utility functions in modules that return booleans to indicate success or failure, but now I see the value of using exception handling - you can easily pass the reason for failure.

1 Like

This edit was incorrect, fixed:

Try 
  Var fileToCreate As FolderItem = SpecialFolder.Documents.Child("any bin or txt.png")
  Call BinaryStream.Create(fileToCreate)
Catch e
  // Shot happens
  MessageBox("Could not create, reason: " + e.Message)
  Quit // Do what you need here
End

:+1:t2: and a code for handling the returned condition more easily.

Just need a bit of attention to avoid code clashes with system error codes for possible real system errors during the operations, like macOS error -8072 for example, :smile: