fat_io_lib
fat_io_lib copied to clipboard
Files with an extension of 1 or 2 characters do not open (use with esp8266)
`void ICACHE_FLASH_ATTR list_html() { FL_DIR dir; struct fs_dir_ent de; char *err = NULL; char buff[512]; char spaces[16]; FILE *fp; size_t len, total_len; char *folder = "/html";
if (fl_opendir(folder, &dir)) {
os_sprintf(buff, "Directory: %s\n\n", folder);
os_printf(buff);
total_len = 0;
while (fl_readdir(&dir, &de) == 0) {
if (!de.is_dir) {
os_sprintf(buff, "%ld", de.size);
len = 7 - strlen(buff);
memset(spaces, ' ', len);
spaces[len] = 0;
os_sprintf(buff, " %s%ld %s\n", spaces, de.size, de.filename);
total_len += de.size;
os_printf(buff);
os_sprintf(buff, "%s%s%s", folder, "/", de.filename);
fp = fopen(buff, "rb");
if (fp == NULL) {
err = "Cannot open file";
os_printf("%s \"%s\". (%s:%u)\n", err, de.filename, __FILE__, __LINE__);
} else {
fclose(fp);
}
}
}
fl_closedir(&dir);
os_printf("\nUsed %d\tbytes\n", total_len);
}
} `
log
`Directory: /html
5866 config.html
6429 favicon.ico
1320 index.html
758 log.html
453 ok.html
2840 scripts.js
Cannot open file "scripts.js". (user_main.c:106) 453 settings.html 2053 style.css 1588 upload.html 266 license 948 main.c Cannot open file "main.c". (user_main.c:106) 948 main.cc Cannot open file "main.cc". (user_main.c:106) 948 main.ccc
Used 24870 bytes`
sorry, the formatting leaves much to be desired
This project is used by Ventoy github project and I found same issue. File 7za.exe would open OK but 7za.xz failed to open. I fixed it by adding a space to the filename extension when calling fopen - "7za.xz "
The fat_io_lib code always seems to assume that there are always either zero or three characters in the extension?
in fat_string.c fatfs_compare_names
// Verify that the file extension lengths match!
if (strlen(ext1) != strlen(ext2))
return 0;
// If they dont match
if (FileString_StrCmpNoCase(ext1, ext2, (int)strlen(ext1))!=0)
return 0;
ext1 could contain xz[/0] and ext2 could contain xz[space] so will fail.
for filename test you use
// Find length without trailing spaces (before ext)
file1Len = FileString_TrimLength(strA, file1Len);
file2Len = FileString_TrimLength(strB, file2Len);
but you do not use FileString_TrimLength for extension test.
I am not very good with C - but here is revised code which seems to work with files with 1, 2 or 3 character file extensions. But you should check it!
Changed file: fat_string.zip
//-----------------------------------------------------------------------------
// fatfs_compare_names: Compare two filenames (without copying or changing originals)
// Returns 1 if match, 0 if not
//-----------------------------------------------------------------------------
int fatfs_compare_names(char* strA, char* strB)
{
char *ext1 = NULL;
char *ext2 = NULL;
int ext1Pos, ext2Pos;
int ext1Len, ext2Len;
int file1Len, file2Len;
// Get both files extension
ext1Pos = FileString_GetExtension(strA);
ext2Pos = FileString_GetExtension(strB);
// NOTE: Extension position can be different for matching
// filename if trailing space are present before it!
// Check that if one has an extension, so does the other
if ((ext1Pos==-1) && (ext2Pos!=-1))
return 0;
if ((ext2Pos==-1) && (ext1Pos!=-1))
return 0;
// If they both have extensions, compare them
if (ext1Pos!=-1)
{
// Set pointer to start of extension
ext1 = strA+ext1Pos+1;
ext2 = strB+ext2Pos+1;
// Verify that the file extension lengths match!
ext1Len = strlen(ext1);
ext2Len = strlen(ext2);
ext1Len = FileString_TrimLength(ext1, ext1Len);
ext2Len = FileString_TrimLength(ext2, ext2Len);
if (ext1Len != ext2Len)
return 0;
// If they dont match
if (FileString_StrCmpNoCase(ext1, ext2, ext1Len)!=0)
return 0;
// Filelength is upto extensions
file1Len = ext1Pos;
file2Len = ext2Pos;
}
// No extensions
else
{
// Filelength is actual filelength
file1Len = (int)strlen(strA);
file2Len = (int)strlen(strB);
}
// Find length without trailing spaces (before ext)
file1Len = FileString_TrimLength(strA, file1Len);
file2Len = FileString_TrimLength(strB, file2Len);
// Check the file lengths match
if (file1Len!=file2Len)
return 0;
// Compare main part of filenames
if (FileString_StrCmpNoCase(strA, strB, file1Len)!=0)
return 0;
else
return 1;
}