我喜欢用mpg321或mplayer来听歌。听同一个文件夹里的歌是很方便的,比如要听 /mnt/songs/chinese/ 里的歌可以用这个命令
mpg321 -Z /mnt/songs/chinese/*
但是我的 chinese 文件夹里还有很多以歌手名字命名的子文件夹,上面那个命令无法听到子文件夹里的歌。
所以我早就想编一个可以生成播放清单的程序,把子文件夹的歌曲也包括在内。
现在学了K&R的第八章,发现里面那个打印目录的例子就是我想要的Playlist Generator!只要把
printf("%8ld %s\n", stbuf.st_size, name);改成
printf("%s\n", name);就可以了!
这样就可以把songs文件夹(
包括子文件夹)的全部歌曲生成一个播放清单了。
./a.out /mnt/songs/ > allsongs.list
可是它把全部文件,包括 .txt 等不是歌曲的文件也放进清单里了,所以我又修改一下,只把歌曲(.mp3 .wma .ogg等后缀的文件)放进清单。
修改后的完整程序如下:
/* K&R section 8.6 */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
void plist(char *);
void dirwalk(char *, void (*fcn)(char *));
/* print file size */
main(int argc, char **argv)
{
if (argc == 1)/* default: current directory */
plist(".");
else
while (--argc > 0)
plist(*++argv);
return 0;
}
void plist(char *name)
{
struct stat stbuf;
char *nsuffix = name+strlen(name)-4;
if (stat(name, &stbuf) == -1) {
fprintf(stderr, "plist: can't access %s\n", name);
return;
}
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
dirwalk(name, plist);
if (strcmp(nsuffix, ".mp3") == 0
|| strcmp(nsuffix, ".wma") == 0
|| strcmp(nsuffix, ".ogg") == 0)
printf("%s\n", name);
}
#define MAX_PATH 1024
void dirwalk(char *dir, void (*fcn)(char *))
{
struct dirent *dp;
DIR *dfd;
char name[MAX_PATH];
if ((dfd = opendir(dir)) == NULL) {
fprintf(stderr, "dirwalk: can't open %s\n", dir);
return;
}
while ((dp = readdir(dfd)) != NULL) {
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
continue;
if (strlen(dir)+strlen(dp->d_name)+2 > sizeof(name))
fprintf(stderr, "dirwalk: name %s/%s too long\n", dir, dp->d_name);
else {
sprintf(name, "%s/%s", dir, dp->d_name);
(*fcn)(name);
}
}
closedir(dfd);
}
如果你也喜欢用 mpg321 等命令行程序来听歌,这个小程序一定可以带给你一点点方便:)