Homebrew [Question] Proper way to create and check for directories

AxiosAmnesia

Member
OP
Newcomer
Joined
Apr 12, 2017
Messages
8
Trophies
0
Age
54
XP
92
Country
United States
I've been writing my own homebrew game recently and I need to write some save files. This itself isn't a problem, but i've been struggling on finding the correct way to handle directory creation and checking for already made directories.

I've found this snippet of code on the forums that has pointed me in the right direction.
Code:
void createDir(const char *path)
{
    FS_Archive sdArch;
    Result Res = FSUSER_OpenArchive(&sdArch, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
    FSUSER_CreateDirectory(sdArch, fsMakePath(PATH_ASCII, path), 0);
}

Is this a good way of going about creating a directory? How would I go about just checking if a directory exists? What about deleting a directory?

Thanks
 
  • Like
Reactions: Quantumcat

erman1337

Well-Known Member
Member
Joined
Sep 27, 2015
Messages
1,211
Trophies
0
Location
Brussels
XP
983
Country
Belgium
Checking directory:
Code:
// this returns 0 on success == false
if(!FSUSER_OpenDirectory(nullptr, sdArch, fsMakePath(PATH_ASCII, "dir path here")){
// directory exists
} else {
// it doesn't
}

Deleting directory:
Code:
// fails if the directory isn't empty
FSUSER_DeleteDirectory(sdArch, fsMakePath(PATH_ASCII, "dir path here"));
// deletes the contents also
FSUSER_DeleteDirectoryRecursively(sdArch, fsMakePath(PATH_ASCII, "dir path here"));
 
Last edited by erman1337,
  • Like
Reactions: Deleted User
D

Deleted User

Guest
I'm still getting a feel for this, this is what I know so far:

All files and directories on your SD Card, as well as in the RomFS of your program, are treated as archives. In order to access an archive, you need to create an FS_Archive, and open it with FSUSER_OpenArchive(). Once you're done with it, close with FSUSER_CloseArchive().

Your method of creating a directory seems fine to me, AFAIK.

Here's a snippet of code I used in a short program a while back to check for directories in the RomFS.

Code:
bool doesDirExist() {
    Handle dirHandle;
    FS_Archive romfsArchive = (FS_Archive) {ARCHIVE_ROMFS, (FS_Path){PATH_EMPTY, 1, (u8*)""}};
    FS_Path path             = fsMakePath(PATH_ASCII, "romfs:/testdir");

    FSUSER_OpenArchive(&romfsArchive, ARCHIVE_ROMFS, path);
    Result ret = FSUSER_OpenDirectory(&dirHandle, romfsArchive, path);

    if (ret) {
        FSDIR_Close(dirHandle);
        FSUSER_CloseArchive(&romfsArchive);
    }

    svcCloseHandle(dirHandle);

    if (ret) return false;
    else return true;
}

Of course, you'd probably want to replace ARCHIVE_ROMFS with ARCHIVE_SDMC, and also add a parameter for the directory path string.
 
Last edited by , , Reason: fix the example, whoops

AxiosAmnesia

Member
OP
Newcomer
Joined
Apr 12, 2017
Messages
8
Trophies
0
Age
54
XP
92
Country
United States
Thanks for the replies.

Checking directory:
Code:
// this returns 0 on success == false
if(!FSUSER_OpenDirectory(nullptr, sdArch, fsMakePath(PATH_ASCII, "dir path here")){
// directory exists
} else {
// it doesn't
}

Deleting directory:
Code:
// fails if the directory is empty
FSUSER_DeleteDirectory(sdArch, fsMakePath(PATH_ASCII, "dir path here"));
// deletes the contents also
FSUSER_DeleteDirectoryRecursively(sdArch, fsMakePath(PATH_ASCII, "dir path here"));

Just went ahead and gave these a test and they both worked for me. Thanks!

I'm still getting a feel for this, this is what I know so far:

All files and directories on your SD Card, as well as in the RomFS of your program, are treated as archives. In order to access an archive, you need to create an FS_Archive, and open it with FSUSER_OpenArchive(). Once you're done with it, close with FSUSER_CloseArchive().

Your method of creating a directory seems fine to me, AFAIK.

Here's a snippet of code I used in a short program a while back to check for directories in the RomFS.

Code:
bool doesDirExist() {
    Handle dirHandle;
    FS_Archive romfsArchive = (FS_Archive) {ARCHIVE_ROMFS, (FS_Path){PATH_EMPTY, 1, (u8*)""}};
    FS_Path path             = fsMakePath(PATH_ASCII, "romfs:/testdir");

    FSUSER_OpenArchive(&romfsArchive, ARCHIVE_ROMFS, path);
    Result ret = FSUSER_OpenDirectory(&dirHandle, romfsArchive, path);

    if (ret) {
        FSDIR_Close(dirHandle);
        FSUSER_CloseArchive(&romfsArchive);
    }

    svcCloseHandle(dirHandle);

    if (ret) return false;
    else return true;
}

Of course, you'd probably want to replace ARCHIVE_ROMFS with ARCHIVE_SDMC, and also add a parameter for the directory path string.

I'm not very familiar with how to use handles, but thank you for your solution.
 

AxiosAmnesia

Member
OP
Newcomer
Joined
Apr 12, 2017
Messages
8
Trophies
0
Age
54
XP
92
Country
United States
For anyone that may come across this thread seeking file i/o questions I found a great example in the citra-emu source code.

https://github.com/citra-emu/hwtests/blob/master/source/tests/fs/fs_sdmc.cpp

Code:
static bool TestFileWriteRead(FS_Archive sdmcArchive)
{
Handle fileHandle;
u32 bytesWritten;
u32 bytesRead;
u64 fileSize;

const static FS_Path filePath = fsMakePath(PATH_ASCII, "/test_file_write_read.txt");
const static char* stringWritten = "A string\n";

// Create file
FSUSER_OpenFile(&fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE | FS_OPEN_WRITE, 0);
SCOPE_EXIT({ // Close and delete file no matter what happens
FSFILE_Close(fileHandle);
FSUSER_DeleteFile(sdmcArchive, filePath);
});

// Write to file
SoftAssert(FSFILE_Write(fileHandle, &bytesWritten, 0, stringWritten, strlen(stringWritten)+1, FS_WRITE_FLUSH) == 0);
// Verify string size
SoftAssert(strlen(stringWritten)+1 == bytesWritten);

// Check file size
SoftAssert(FSFILE_GetSize(fileHandle, &fileSize) == 0);
// Verify file size
SoftAssert(fileSize == bytesWritten);

std::unique_ptr<char> stringRead(new char[fileSize]);
// Read from file
SoftAssert(FSFILE_Read(fileHandle, &bytesRead, 0, stringRead.get(), fileSize) == 0);
// Verify string contents
SoftAssert(strcmp(stringRead.get(), stringWritten) == 0);

return true;
}
 
  • Like
Reactions: Deleted User

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Psionic Roshambo @ Psionic Roshambo: https://www.youtube.com/watch?v=HHNH5pnioQk