初识TypeScript:查找指定路径下的文件按类型生成json

下面的方法为查找指定路径下的文件,并将所有文件的绝对路径存储到一个临时的数组中:

复制代码

1 let temp: string[] = new Array();

2 function fileDisplay(filePath: string) {

3    // 根据文件路径读取文件,返回一个文件列表

4    const files = fs.readdirSync(filePath);

5    // 遍历读取到的文件列表

6    for (let filename of files) {

7        // path.join得到当前文件的绝对路径

8        const filepath = path.join(filePath, filename);

9        // 根据文件路径获取文件信息

10        const stats = fs.statSync(filepath);

11        const isFile = stats.isFile(); // 是否为文件

12        const isDir = stats.isDirectory(); // 是否为文件夹

13        if (isFile) {

14            temp.push(filepath);

15        }

16        if (isDir) {

17            fileDisplay(filepath); // 递归,如果是文件夹,就继续遍历该文件夹里面的文件

18        }

19    };

20 }

复制代码

注意在上述的方法中需要需要同步读取文件(Sync),而不应该采取默认的异步读取,这样之后的代码中取到temp数组时才会得到正确的值,如果非要异步读取,则需要用回调的方式来写json。

为了获得命令行中输入的参数,可以使用下面的语句:

let argument = process.argv.splice(2);

process.argv()为node.js中返回当前命令行参数的方法,其中2代表的是实际输入的参数数组,如果输入0的话则代表获取node,1的话返回执行的js的完整路径

之后直接将命令行输入的第一个参数,也就是用户键入的文件夹路径作为参数传递给fileDisplay方法即可:

fileDisplay(argument[0]);

得到所有的文件路径后,接下来就是按照文件的类型写入json中了

首先我们需要先遍历所有的文件路径,通过路径字符串可以得到文件的一些基本信息,例如文件的拓展名,文件的基本名称等,通过文件的扩展名可以对文件资源的类型重定义和分类:

1 for (let item of temp)

2 {

3    let extname = path.extname(item);//获取文件的扩展名,带.

4    let basename = path.basename(item, extname);//获取文件的基本名称,第二个参数为需要剔除的扩展名

5    //...

6 }

当然了,如果你不想用path模块的方法,也可以直接用字符串的方式来截取:

    let fileExtension = item.substring(item.lastIndexOf('.'));

//

    let fileName = item.substring(item.lastIndexOf('\\') + 1, item.lastIndexOf('.'));

需要注意的是,在ts中遍历元素内容的方式为of而非in(习惯C#了这里被坑了一把),in只能遍历出索引...

另外,匹配[\]时需要用两个[\\]才可以,因为一个[\]代表的大多为转义字符。

根据文件的扩展名返回自定义的文件类型:

复制代码

1 function GetType(extension: string): string {

2    switch (extension) {

3        case ".png":

4        case ".jpg":

5            return "image";

6        case ".fnt":

7            return "bitmapFont";

8        case ".TTF":

9        case ".ttf":

10            return "font";

11        case ".spine":

12        case ".particle":

13            return "particle";

14        case ".mp3":

15            return "audio";

16        default:

17            return "null";

18    }

19 }

复制代码

筛选过滤文件:

复制代码

1    let type = GetType(extname);

2    //过滤非指定类型文件

3    if (type == "null")

4        continue;

5    //过滤重名文件

6    if (resources[basename]) {

7        console.log(`错误!!!该文件名已存在【${basename}】`);

8        continue;

9    }

复制代码

定义json基础数据结构:

复制代码

1 let outjson: any = {}

2 let resources: any = {};

3 let d: any = {};

4

5 d.tye = type;

6 d.url = item;

7

8 resources[basename] = d;

9 outjson.resources = resources;

复制代码

上面是为了更方便读者理解而将这三个变量放在一起,实际上变量d是在循环体内部声明的局部变量,any类型是ts中的一种特殊类型,它可以被定义为任何一种其他类型,这里将它定义为了一种大括号类型的数据结构,代表它的内部还有一些其他的任意成员变量。

如果是在C#中书写json的数据结构,将是一件非常麻烦的事,需要严格的定义为一个新的类或结构体,但ts中似乎相当自由,只需要用一个变量来代替即可,甚至直接在赋值初始化的时候来确定键值。

但网上关于大括号类型的any讲解并不多,所以做了一点额外的测试:

复制代码

1 let a: any = {};

2 let b: any = {};

3 let c: any = {};

4 a.b = "c";

5 a.c = 5.6;

6 a.a = a.b;

7 a["b"] = a.b;

8 b["c"] = a.c;

9 b["a"] = a;

10 c.a = b;

11 c[a.b] = a;

12 console.log(c);

复制代码

大家可以推导下会打印出什么结果;好,接下来公布答案:

复制代码

1 {

2    a: {

3        c: 5.6,

4        a: {

5            b: 'c',

6            c: 5.6,

7            a: 'c'

8        }

9    },

10    c: {

11        b: 'c',

12        c: 5.6,

13        a: 'c'

14    }

15 }

复制代码

下面来进行一个简单的梳理:

测试第四行 代表a中有一个键(变量名)为b的成员,它的值为字符串c

测试第五行 代表a中有一个键(变量名)为c的成员,它的值为数字类型5.6(ts中所有的数字类型均为浮点型,省去了很多其他编程语言中值类型数据的繁琐分类)

测试第六行 代表a中有一个键(变量名)为a的成员,它的值初始化为a中键为b的那个成员的值,也即是同样的字符串c

测试第七行 实际意义与第四行相同,但这里是为了测试[key]这种书写形式所存在的意义,实际上结合第十一行就能得出结论,那就是——当我们需要一个字符串变量而非常量来作为键时就不能直接用“.成员名”的方式了,因为这样的方式只能生成固定的字符串名,

可以再比较以下例子:

复制代码

1 let x1: any;

2 let x2: any = {};

3 x1 = "x2";

4 x2.x1 = x1;

5 x2[x1] = x1;

6 console.log(x2);

7 x1 = "6";

8 x2.x1 = x1;

9 x2[x1] = x1;

10 console.log(x2);

复制代码

大家可以再推导一下会打印出什么结果;好,现在公布答案:

复制代码

1 {

2    x1: 'x2',

3    x2: 'x2'

4 } {

5    '6': '6',

6    x1: '6',

7    x2: 'x2'

8 }

深圳网站建设www.sz886.com