[Question] Proper way to create and check for directories

Discussion in '3DS - Homebrew Development and Emulators' started by AxiosAmnesia, Apr 20, 2017.

  1. AxiosAmnesia

    AxiosAmnesia Newbie

    Apr 12, 2017
    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.
    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?

    Quantumcat likes this.
  2. erman1337

    erman1337 GBAtemp Maniac

    Sep 27, 2015
    Checking directory:
    // 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:
    // 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, Apr 21, 2017
    B_E_P_I_S_M_A_N likes this.
  3. B_E_P_I_S_M_A_N

    B_E_P_I_S_M_A_N can't think of anything creative to put here

    Jun 7, 2016
    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.

    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) {
        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 B_E_P_I_S_M_A_N, Apr 21, 2017 - Reason: fix the example, whoops
  4. AxiosAmnesia

    AxiosAmnesia Newbie

    Apr 12, 2017
    United States
    Thanks for the replies.

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

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

    AxiosAmnesia Newbie

    Apr 12, 2017
    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.


    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
    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;
    B_E_P_I_S_M_A_N likes this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice