PSP Development/Filesystem/Iterating Directories

Iterating directories is core for loading data from folders such as music players, video players, and picture viewers whom rely on searching directories to list files available to play. Recursion can be used together with iteration to view all files in a given directory - even the root. File iteration is a similar method, which includes a struct SceIoStat, to opening and modifying files.

Opening A Directory edit

Directories must be opened in order to view the contents. PSPDEV gives sceIoDopen() as opposed to sceIoOpen() for files. However, a file handle is returned from the call and takes in a const char*. If the number is less than or equal to 0, there must be an error.

	const char* src = ROOT;
	
	int uid = sceIoDopen(src);

Closing A Directory edit

Directories opened, like files, must be closed. Multiple directories can be open, however, unless using recursion, it is advised to not open multiple directories all at once. It is also advised to not open them at the start of the program while leaving them open until the end. The PSP is a powerful machine, but bad practices like littering RAM, especially dangerous in IO using buffers, can snowball into waste of memory, unmanageable code, and poor functionality. Directories can be closed using the SceIoDclose() function. It returns an integer stating if there was a failure, which should be handled.

	int status = sceIoDclose(uid);

Listing Files edit

Inside directories lay files. The struct SceIoDirent stands for "Directory entry," which holds information about the directory. In order to load information into this struct, a call to sceIoDread() function needs to take place. This only gets one file at a time. This means the sceIODread() function will load in data for one file from the directory into the struct. A while loop can be used to iterate through all the files. There is also a SceIoStat, which tells the size and time attributes of the folder. Since there is no path associated with the name of the file in SceIoDirent, one could use snprintf() from <stdio.h> to format a string - additionally using sceIoOpen() to open another file.

void get_files() {
	
	const char* src = ROOT;
	
	// open the directory
	int uid = sceIoDopen(src);
	if(uid <= 0)
		crash(uid, "Directory Iteration", "Failure or empty directory");
	
	printf("Opened, reading directory.\n");
	
	// iterate over the directory for files, print name and size of array (always 256)
	// this means you use strlen() to get length of file name
	SceIoDirent dir;
	char temp_name[PATH_MAX]; // 4096 is linux's forced policy
	while(sceIoDread(uid, &dir) > 0) {
		printf("Read `%s` (%d) \n", dir.d_name, sizeof(dir.d_name));
		
		// format a path, print it (remember to include stdio.h)
		snprintf(temp_name, PATH_MAX, "%s%s", src, dir.d_name);
		printf("@%s\n", temp_name);
	}
	
	printf("Done reading directory.\n");
	
	// clean up
	sceIoDclose(uid);
}