文件名映射
作用
前文已经提到了SD卡模块不能读取中文名,会出现很多奇奇怪怪的bug,而且我要使用DF Mini Player这个模块来播放MP3(ESP8266Audio已经被我放弃了),也需要特定格式的文件名,比如说我用playFolder(1,2)函数,文件名必须为"/01/002",所以做一个文件名的映射很有必要。
思路
在根目录下创建music_setting.txt这个配置文件,里面保存了以下数据:
- 总文件夹的个数
- 每个文件夹对应的名称
然后在每个文件夹下面创建setting.txt这个配置文件,以下内容:
- 音频文件的个数
- 每个音频文件对应的名称
实现
这个是我自己想的格式:
- 第一行是数字,表示个数
- 第二行开始,以@开头表示映射起点,然后每一个映射都是这样的结构:储存的名字?中文名#
比如说我的这个文件结构:
最后就是代码的读取:
读取文件夹:
String documents;
int doc_num = 0;
bool initDocuments()
{
if(!SD.exists("/_music_setting.txt"))
return false;
File file = SD.open("/_music_setting.txt", FILE_READ);
if(file.available())
{
char c1 = file.read();
char c2 = file.read();
if((c2 == '\n') || (c2 == '\r'))
{
doc_num = char_to_int(c1);
}
else
{
char arr[2] = {c1,c2};
doc_num = charArr_to_int(arr,2);
file.read();
}
file.read();
}
if(file.available())
{
char c = file.read();
if(c != '@')
{
file.close();
Serial.println("not correct format!");
return false;
}
}
while(file.available())
{
char indexName[3];
char exactName[56];
int i = 0;
while(file.available())
{
char c = file.read();
if((c == '\n') || (c == '\r'))
continue;
if(c == '?')
break;
indexName[i] = c;
i++;
}
indexName[i] = '\0';
Serial.println(indexName);
i = 0;
while(file.available())
{
char c = file.read();
if((c == '\n') || (c == '\r'))
continue;
if(c == '#')
break;
exactName[i] = c;
i++;
if(i >= 55)
break;
}
exactName[i] = '\0';
Serial.println(exactName);
if(documents == "")
{
documents = exactName;
}
else
{
documents = documents + " \n " + exactName;
}
}
file.close();
return true;
}
读取文件大同小异:
String files;
int file_num = 0;
bool initFiles()
{
String dirName = "/";
if(selected_document < 10)
dirName += '0';
dirName += String(selected_document);
Serial.println(dirName);
if(!SD.exists(dirName + "/_setting.txt"))
return false;
File file = SD.open(dirName + "/_setting.txt");
if(file.available())
{
char c1 = file.read();
char c2 = file.read();
if((c2 == '\n') || (c2 == '\r'))
{
file_num = char_to_int(c1);
}
else
{
char arr[2] = {c1,c2};
file_num = charArr_to_int(arr,2);
file.read();
}
file.read();
}
if(file.available())
{
char c = file.read();
if(c != '@')
{
file.close();
Serial.println("not correct format!");
return false;
}
}
while(file.available())
{
char indexName[4];
char exactName[56];
int i = 0;
while(file.available())
{
char c = file.read();
if((c == '\n') || (c == '\r'))
continue;
if(c == '?')
break;
indexName[i] = c;
i++;
}
indexName[i] = '\0';
Serial.println(indexName);
i = 0;
while(file.available())
{
char c = file.read();
if((c == '\n') || (c == '\r'))
continue;
if(c == '#')
break;
exactName[i] = c;
i++;
if(i >= 55)
break;
}
exactName[i] = '\0';
Serial.println(exactName);
if(files == "")
{
files = exactName;
}
else
{
files = files + " \n " + exactName;
}
}
file.close();
return true;
}
其中有部分细节被我省略,着重看文件处理部分,然后再结合上次提到的SelectionList功能,就可以得到这个结果(视频后续上传)