Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a FileAccess method to fill a file with zeros for X amount of times #9467

Closed
Gianpy16 opened this issue Apr 7, 2024 · 2 comments
Closed
Milestone

Comments

@Gianpy16
Copy link

Gianpy16 commented Apr 7, 2024

Describe the project you are working on

I'm working on a tool to build 3D maps from a custom format I'm developing, I've chosen to write map data inside binary files with informations about mesh and collision.
These files don't store a mesh itself, but store enough data to build one.

Describe the problem or limitation you are having in your project

When I create these files I first fill with with dummy data with a buffer full of zeros so I will make one single file resize call to the system, then I seek at the beginning of the file and write the actual data I want.
The problem is that Godot does not have a way to quickly create a dummy file with x amount of bytes and I need to use an hacky way to achieve such a thing, I'll show how I've implemented the solution in gdscript in the next sections of this issue.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The feature I wish could be implemented into the engine is a new method defined like so:

FileAccess.store_empty(size: int) -> void

Wich write inside the file 8 bits of zeros for size amount of times.
Immedialy make writing a dummy file as a single function call inside the script.

Other names I can think of that can be given to this function may be store_0 or store_null.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

func _ready () -> void:
    var file := FileAccess.open("res://map_data.bin", FileAccess.WRITE);
    file.store_empty(2048); # Allocate 2048 empty bytes inside the file as a single call.
    file.seek(0);
    
    # ... Write inside the file with actual data we want to store. The space of the file has already been allocated.

If this enhancement will not be used often, can it be worked around with a few lines of script?

This a simplified version of what I'm using inside my code, the main problem is that it will create an array in RAM filed with zero and then it will copy each zero into the file.

func store_empty (file: FileAccess, size: int) -> void:
    assert(file != null, "Need a file to write.");
    assert(size >= 0, "Need at least one byte to write.");
    
    var buffer := PackedBytesArray();
    buffer.resize(size);
    file.store_buffer(buffer);

The problem is that allocating the RAM and then copy from it the number zero is a waste of resources by the computer, at this point it will make slower to make a dummy file.

Another way it could be calling store_8 for the amount of bytes we want to create the dummy file but it is agaist the porpouse of making this in a single resize call.

Is there a reason why this should be core and not an add-on in the asset library?

The way this is achieved in gscript is an hacky way to solve such simple problem, this is why I think it should be implemented into the engine itself.
If this feature gets implemented it will help creating dummy file into a simple and quick function call.

@bruvzg
Copy link
Member

bruvzg commented Apr 8, 2024

The closest thing is probably exposing something like:

#ifdef WINDOWS_ENABLED
::_chsize(fd, size);
#else
::ftruncate(fd, size);
#endif

But these functions (depending on FS and platform) usually do not allocate any real disk space, and probably won't be any faster than using store_8. But it can be useful for shrinking existing files.

Proposal is more or less equivalent to #6776

@Calinou Calinou changed the title Implement a function to fill a file with zeros for x amount of times. Add a FileAccess method to fill a file with zeros for X amount of times Apr 8, 2024
@akien-mga
Copy link
Member

Implemented by godotengine/godot#90403.

@akien-mga akien-mga added this to the 4.3 milestone Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants