简体   繁体   English

在C中使用dirent.h读取和选择文件

[英]Reading and selecting files using dirent.h in C

I'm new into programming microcontrollers, and I have a problem. 我是微控制器编程的新手,但遇到了问题。

I'm trying to make a device that plays music from USB. 我正在尝试制作一种可以播放USB音乐的设备。 I can read from USB, but I have no idea how to choose a certain file. 我可以从USB读取,但是我不知道如何选择某个文件。 I'm using dirent . 我正在使用dirent

My code so far: 到目前为止,我的代码:

while (true) {
    USBHostMSD msd("usb");
     //setup PWM hardware for a Class D style audio output
    PWMout.period(1.0/400000.0);

    // wait until connected to a USB device
    while(!msd.connect()) {
        Thread::wait(500);
    }

    FILE *wave_file;
    lcd.cls();
    lcd.locate(0,3);


    DIR *dir;
    struct dirent *ent;
    int i=0;
    int stevilo_datotek =0;


    dir = opendir ("/usb/");
    if (dir != NULL) 
    {


        while ((ent = readdir (dir)) != NULL) 
        {   
              lcd.printf ("%s\n", ent->d_name[0]);  
        }
}

Now this code displays what's on USB. 现在,此代码显示USB上的内容。 How can I navigate through files on USB using the buttons on the device? 如何使用设备上的按钮浏览USB上的文件? I'd like to know if there's a way to assign certain song a certain number so I can navigate. 我想知道是否可以为某些歌曲分配一定的编号,以便进行导航。 I've studied dirent.h file for so long, and I can't find where dirent saves the file order (if it does). 我已经研究了dirent.h文件很长时间,但找不到dirent将文件顺序保存在哪里(如果有的话)。

You may be confusing the purpose of dirent.h In short it may be difficult to see the forest for the trees. 您可能会混淆dirent.h的目的。简而言之,可能很难看到树木茂盛的森林。

You can read the information (ent->d_name, note that ent->d_name is a pointer to an array of chars, often called a 'string') into a data structure (like an array or a list), then use that struct with code that detects button presses to move an index into the array information either up or down (to a greater or lesser index, make sure to check that your index doesn't go outside the range or your structure). 您可以将信息(ent-> d_name,请注意ent-> d_name是指向字符数组的指针,通常称为“字符串”)读入数据结构(如数组或列表)中,然后使用该结构使用检测按钮按下的代码将索引向上或向下移动到数组信息中(对于更大或更小的索引,请确保您的索引没有超出范围或结构)。 Or you can create code where your while loop waits on a button press and only reads the file name then (using seekdir to go backwards). 或者,您可以创建代码,使while循环等待按钮按下,然后仅读取文件名(使用seekdir向后移动)。

UPDATE (to response to comment): Keep in mind that filesystems are tree structures like so: 更新(以回应评论):请记住,文件系统是树形结构,如下所示:

 / (root) +--- dir1 ----------------------------+- dir1.1 ---- dir2 (empty) -- file1.1 ---- dir3 ---- dir3.1 +--- file3.1 ---- file1 ---- file3.2 ---- file2 

You have to decide how to handle that, are you going to only support one directory (make them put all their music files in one place), allow them to navigate directories, or look through all directories selecting only files you know how to play? 您必须决定如何处理,是仅支持一个目录(让他们将所有音乐文件放在一个位置),还是让他们浏览目录,或者浏览所有目录,仅选择您知道如何播放的文件?

There is no inherit order to the files (or sub-directories) and in some systems files can be added or deleted at any time. 文件(或子目录)没有继承顺序,在某些系统中,可以随时添加或删除文件。

Here is a very simple-minded example of one way to keep the list of directory entries: 这是保存目录条目列表的一种非常简单的示例:

char *names[400]; // make space for 400 names
int ix;
ix = 0;
if (dir != NULL) 
{
     while ((ent = readdir (dir)) != NULL) 
     {   
           lcd.printf ("%s\n", ent->d_name[0]);  
           // allocate memory to store the name
           names[ix] = (char*) malloc(strlen(ent->d_name)); // strlen from string.h 
                                                            // malloc from stdlib.h
           // copy the name from the directory entry
           strcpy(names[ix], ent->d_name); // strcpy from string.h
           ix++;
           if (ix >= 400) 
           {
               // do something because your array isn't big enough
           }
     }
}

Now you have your names in the array 'names' and can address them by index. 现在,您在数组“名称”中有了您的名称,并可以通过索引对其进行寻址。 The value 'ix-1' is your last name, 0 is your first name. 值“ ix-1”是您的姓氏,0是您的名字。 Your button presses can increment/decrement the index into your name array which identifies the name you want. 按下按钮可以将索引增加/减少到名称数组中,该索引标识您想要的名称。 Keep in mind that some of those names might be directory names rather than file names. 请记住,其中一些名称可能是目录名称,而不是文件名称。

Admittedly this is simply-minded, you might want to allocation the array rather than use a fixed value (in fact you have to if you want to pass the 'names' array to a calling function), there are "secure" versions of strcpy (meant to help prevent memory overflow corruption), etc. but it should give you an idea about how you can keep the names in memory. 诚然,这很简单,您可能想分配数组而不是使用固定值(实际上,如果要将“ names”数组传递给调用函数,则必须这样做),有“安全”版本的strcpy (旨在帮助防止内存溢出损坏)等,但它应该使您了解如何将名称保留在内存中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM