Hi! My application needs to give the user the possibility to rename files created by the application itself in a specific folder. I’ve tried different approaches but none worked:
DirAccess.rename_absolute(oldFilePath, newFilePath): this function deletes all other files in the folder except the “renamed” one, which doesn’t get renamed anyway…
OS.execute(...): didn’t work and it’s too OS dependent so I would much rather avoid it.
DirAccess.copy(old, new) + DirAccess.remove(old): this approach fails at copy with debugger saying it failed accessing all files in the folder.
I also tried instantiating the DirAccess through the open() method, then tried the rename() function (same result as rename_absolute()) and also tried copy/remove, which gives the same error as the static functions.
Any idea on how to do this? Do I really have to delve into the OS.execute different OS ways to do stuff? Do I need a C# script to do it? What am I missing?
Thanks in advance for the help
var dirPath : String = folder_path()
for row : Control in fileRowsContainer.get_children():
var old : String = dirPath + row.get_child(0).name
var new : String = dirPath + row.get_child(0).text
if old != new:
DirAccess.rename_absolute(old, new)
fileRowsContainer has 1 Control row children for each file in the folder which has as first child a TextEdit, each TextEdit is setup at first with properties name and text set as the original file name, and when the user closes the UI the code above is triggered to rename when it finds a difference between the 2 properties. The result is what described in the topic: the file is not renamed and all other files in the folder are deleted. Let me know if you need a console output of the filepaths I can provide it (I already tried making it delete the file when TextEdit properties differs and it works correctly so I doubt it’s a path related problem on my end).
Other disclaimers: the names are edited preserving file extension and I have enabled the “show hidden elements” in the file explorer. Searching all the inadvertedly deleted files in the whole filesystem doesn’t find any results.
I’m using rename() in Stahldrache without seeing this kind of behavior (when I save data I write to a temp file and then rename it over top of the real file once I’m sure it’s fully written and good…).
You may also be getting bitten by new being a keyword. Maybe make it old_name and new_name?
DirAccess.rename_absolute() returns an Error. Try printing it:
var error: Error = DirAccess.rename_absolute(from, to)
print(error_string(error))
Even if it fails, there should be no way it deletes any files. If it doesn’t fail and the files are not where they are supposed to be, they got renamed to something you didn’t expect.
@normalized true, but I do and I know what the file names are and always pay attention not to call them the same. I will definitely add a check once the basic feature works properly.
@hexgrid Windows 11. I just tried changing variable names but still behaves as described previously, I will keep them with the suffix you suggested for safety tho.
@zigg3c All it prints is Failed. Nothing more, nothing less
The most likely culprit is wrong filepaths. That means that whatever paths you are passing to the function are somehow malformed/incorrect. Try printing them out.
The second most likely culprit is something to do with permissions, but we won’t need to get into that before we check the first one.
I found the problem, you’re all right it’s the paths. I did print them before, but I also did miss the problem with it (I’ve been working on fixing this for the past 2 days, I’ve got logs everywhere, meaning too many). When assigning the old filename to the TextEdit name property the extension . is changed to _ by Godot itself, therefore the rename fails because it cannot find the original file to rename. I removed the file extension from TextEdit name and text properties, adding it back later in the process before calling the rename function, and it worked fine, sorry for being a bit dented
That said, the side-effect of some files “disappearing” from the folder when the rename function is called with a wrong first argument for all files in the folder is still “mysterious” to me and I can still easily reproduce it by changing a . into a _. In a live application the consequences of this weird behavior could be problematic, in particular since Godot itself has an automatic process to convert . into _. If it can help from my testing if the rename function is called with a wrong first argument for less then all the files in the folder it just doesn’t rename but also the files don’t disappear. If all files in the same folder are renamed with a wrong first argument most files in that same folder disappear.
Also the error could be a little bit more verbose than Failed, and the debugger error console is completely silent about it.
You should forbid anything other than alphanumeric characters in those filenames. Also mixing node names and file names doesn’t sound like a good idea. Use node’s metadata instead to store the filename string.
Right. Godot doesn’t allow . in Node names. It will convert any . into _ and popup and error saying as much. I’ve just tested that and I couldn’t possibly have tought about that being a factor since I’ve never tried using . in Node names, hah!
And you’re absolutely right! If you do this in code:
name = "hello.world"
It will not print an error, and will silently replace the . with _. If there isn’t one, you should probably create a git issue. I’ll do that tomorrow if nobody wants to in the meantime.