用户:
Nomen查看:2 回复:6 评论:2 创建时间:2023-05-18T12:32:06
这里是没有开场白的Nomen,我注意到很多场景下NomenSQLite不能很方便地处理一些公用数据或储存,同时我觉得神岛地文件系统过于限制,所以我写了一个基于SQL的文件与目录管理系统
-----------
请注意!NomenFileSystem1.0.0依赖于NomenSQLite1.2.0
请先使用此链接升级到1.2.0,否则会出现错误:
shequ.codemao.cn/wiki/forum/540732
-----------
NomenFileSystem本体:
class NomenFS {
constructor() {
if (!this.operator) this.operator = (new NomenSQLite()).operate('NomenFileSystemMain');
if (NomenFS.instance) return NomenFS.instance;
}
static async launch() {
if (NomenSQLite) var ns = NomenSQLite;
else throw new Error('NomenSQLite不存在')
let NSqlite = await ns.launch({
'NomenFileSystemMain': [
{ name: 'type', type: ns.DataType.TEXT, notnull: true },
{ name: 'path', type: ns.DataType.TEXT, notnull: true },
{ name: 'parent', type: ns.DataType.TEXT, notnull: true },
{ name: 'creationdate', type: ns.DataType.TEXT, notnull: true },
{ name: 'property', type: ns.DataType.TEXT, notnull: true },
{ name: 'owner', type: ns.DataType.TEXT },
{ name: 'file', type: ns.DataType.TEXT },
]
}, ns.LaunchAction.CREATE_OR_LAUNCH, (v, r) => { if (r) throw NomenFS.ErrorGenerator('0', r) });
if (!this.instance) this.instance = new this();
if (!this.operator) this.operator = NSqlite.operate('NomenFileSystemMain');
return this.instance;
}
/** 静态方法 */
static getInstance() {
if (!this.instance) {
this.instance = new NomenFS();
}
return this.instance;
}
static ErrorGenerator(errorcode, errMessage) {
return new Error(`[NomenFileSystem: ErrorCode:${errorcode}] ${NomenFS.ErrorCode[errorcode]}${errMessage ? ' : ' + errMessage : ''}`)
}
static pathSolver(path) {
if (typeof path == "string") {
if (path.startsWith('.')) path = path.substring(1);
if (!path.startsWith('/')) path = `/${path}`;
}
return path;
}
static filePropertyGenerator(property) {
let init = {
readonly: false,
}
Object.assign(init, property);
return init;
}
/** 静态属性 */
static fileType = {
'file': 'file',
'folder': 'folder'
}
static ErrorCode = {
"-3": 'Must specify a file name or folder name',
"-2": 'The file name must not contain the following characters:[ "/" ":" "?" """ "<" ">" "\'" "|" "\\" "*" "~" ]',
"-1": 'Incoming parameters do not match expectations',
"0": 'Unexpected errors',
"1": 'File does not exist',
"2": 'Folder does not exist',
"3": 'A file or folder with the same name already exists in the current location'
}
/** 实例方法 */
_pathParser(path) {
let p = path.split('/').slice(0, -1).join('/');
let c = path.split('/').slice(-1);
if (/[/:?"<>|~'\\*]/g.test(c)) throw NomenFS.ErrorGenerator("-2");
if (!c.length) throw NomenFS.ErrorGenerator("-3");
return { parentFolder: p.length ? p : '/', currentFile: c[0] }
}
async readFile(path) {
if (typeof path != "string") throw NomenFS.ErrorGenerator("-1");
let result = await NomenFS.operator.select('path', NomenFS.pathSolver(path));
if (result.length) return result[0].file;
else throw NomenFS.ErrorGenerator("1");
}
async writeFile(path, content, readonly = false) {
path = NomenFS.pathSolver(path);
if (typeof path != "string" || typeof content !== "string") throw NomenFS.ErrorGenerator("-1");
let cpath = this._pathParser(path);
let ctn = {
type: NomenFS.fileType['file'],
path,
parent: cpath.parentFolder,
creationdate: Date.now(),
property: JSON.stringify(NomenFS.filePropertyGenerator({ readonly })),
file: content,
};
let prt = await NomenFS.operator.select('path', cpath.parentFolder);
if (!prt.length || prt[0].type != NomenFS.fileType['folder']) throw NomenFS.ErrorGenerator("2");
let crt = await NomenFS.operator.select('path', path);
if (crt.length && crt[0].type == NomenFS.fileType['folder']) throw NomenFS.ErrorGenerator("3");
if (crt.length) await NomenFS.operator.update(`path="${path}"`, ctn)
else await NomenFS.operator.insert(ctn);
return path;
}
async mkdir(path, readonly = false) {
path = NomenFS.pathSolver(path);
if (typeof path != "string") throw this.ErrorGenerator("-1");
let fd = await NomenFS.operator.select('path', path);
let cpath = this._pathParser(path);
if (fd.length && fd[0].type == NomenFS.fileType['file']) throw NomenFS.ErrorGenerator("3");
if (!fd.length) {
await NomenFS.operator.insert({
type: NomenFS.fileType['folder'],
path,
parent: cpath.parentFolder,
creationdate: Date.now(),
property: JSON.stringify(NomenFS.filePropertyGenerator({ readonly })),
});
if(cpath.parentFolder) await this.mkdir(cpath.parentFolder)
}
return path;
}
async unlink(path) {
if (typeof path != "string") throw NomenFS.ErrorGenerator("-1");
return await NomenFS.operator.remove('path', NomenFS.pathSolver(path));
}
async readdir(path) {
path = NomenFS.pathSolver(path);
if (typeof path != "string") throw NomenFS.ErrorGenerator("-1");
if (path == '/') return (await NomenFS.operator.select('parent', '/')).map(v => v.path);
let parentFolder = await NomenFS.operator.select('path', path);
if (!parentFolder.length) throw NomenFS.ErrorGenerator("2");
if (parentFolder.length && parentFolder[0].type == NomenFS.fileType["file"]) throw NomenFS.ErrorGenerator("3");
return (await NomenFS.operator.select('parent', path)).map(v => v.path);
}
async rmdir(path) {
path = NomenFS.pathSolver(path);
if (typeof path != "string") throw NomenFS.ErrorGenerator("-1");
let targetFolder = await NomenFS.operator.select('path', path);
if (!targetFolder.length) throw NomenFS.ErrorGenerator("2");
let childFolder = await NomenFS.operator.select('parent', path);
if (childFolder.length) {
for (let i = 0; i < childFolder.length; i++) {
if ((await NomenFS.operator.select('parent', childFolder[i].path)).length) await this.rmdir(childFolder[i].path);
await NomenFS.operator.remove('path', childFolder[i].path);
}
}
await NomenFS.operator.remove('path', path);
return path;
}
async appendFile(path, content) {
path = NomenFS.pathSolver(path);
if (typeof path != "string") throw NomenFS.ErrorGenerator("-1");
let tf = await NomenFS.operator.select('path', path);
if (!tf.length) throw NomenFS.ErrorGenerator("1");
if (tf[0].type == NomenFS.fileType["folder"]) throw NomenFS.ErrorGenerator("3");
await this.writeFile(path, tf[0].file.concat(content));
return path;
}
async rename(path, newname) {
path = NomenFS.pathSolver(path);
if (typeof path != "string") throw NomenFS.ErrorGenerator("-1");
let tt = await NomenFS.operator.select('path', path);
if (!tt.length) throw NomenFS.ErrorGenerator("1");
if (tt[0].type == NomenFS.fileType["file"]) {
await NomenFS.operator.update(`path=${path}`, { path: path.replace(/\/[^\/]*$/, '/' + newname) });
} else if (tt[0].type == NomenFS.fileType["folder"]) {
function cname(rname, match) {
for (let i = 0; i < rname.length; i++) { if (match[i] && (match[i] != rname[i])) { rname[i] = match[i]; break; } }
return rname;
}
function inpath(rname, match) {
for (let i = 0; i < rname.length; i++) { if (match[i] && (match[i] != rname[i])) return true; }
return false;
}
let allFile = await NomenFS.operator.select('*');
for (let i = 0; i < allFile.length; i++) {
if (!inpath(allFile[i].path.split('/').slice(1), path.split('/').slice(1))) {
console.log(allFile[i].path + ' // ' + `/${cname(allFile[i].path.split('/').slice(1), path.replace(/\/[^\/]*$/, '/' + newname).split('/').slice(1)).join('/')}`)
await NomenFS.operator.update(`path=${allFile[i].path}`, {
path: `/${cname(allFile[i].path.split('/').slice(1), path.replace(/\/[^\/]*$/, '/' + newname).split('/').slice(1)).join('/')}`,
parent: `/${cname(allFile[i].path.split('/').slice(1), path.replace(/\/[^\/]*$/, '/' + newname).split('/').slice(1)).join('/')}`
});
}
}
}
return path;
}
}
API示例:(注:所有的函数都绑定在实例上,并且所有的函数都是异步函数)
/**
* 读取文件内容
* @param {string} path 路径
*/
ns.readFile('/src/playerData/nomen.json');
/**
* 写入文件内容
* @param {string} path 路径
* @param {string} content 文本内容
*/
ns.writeFile('/src/playerData/nomen.json','"{name:\\"Nomen\\",coin:10},bag:[\\"By NomenTeam - Nomen\\",\\"EasyCoding\\"]"');
/**
* 创建文件喵件夹路径,自动创建子文件夹
*/
ns.mkdir('/src/playerData');
/**
* 删除文件
* @param {string} path 路径
*/
ns.unlink('/src/playerData/nomen.json');
/**
* 读取文件夹下的第一层子目录
* @param {string} path 路径
*/
ns.readdir('/src/playerData');
/**
* 删除文件夹
* @param {string} path 路径
*/
ns.rmdir('/src/playerData');
/**
* 将文本内容写入到文件的最后
* @param {string} path 路径
* @param {string} content 文本内容
*/
ns.appendFile('/usr/.config/NomenSQLiteConfig.env','tables = "{}"');
/**
* 重命名文件或文件喵径
* @param {string} newname 新名字
*/
ns.rename('/src/playerData/nomen.json','nomenyyds.json');
NomenEasyCoding项目 - EasyController 是由萌新大佬开发的一款便于管理文件,代码的便捷工具
快速开始:
/**
* EasyController 是由萌新大佬开发的一款便于管理文件,代码的便捷工具
* 此工具完全开源,免费试用,共所有人学习与参考
* 建议单独设立文件使用,并首个require
* @author 萌新大佬 <https://box3.codemao.cn/u/mxdlorzorz>
* @version 1.0.0
*/
//init
const assetTypes ={
'js':'代码',
'image':'图片',
'lut':'滤镜',
'snow':'雪花纹样',
'mesh':'模型',
'sound':'音乐/音效',
'directory':'文件夹',
};
!function init(){
console.clear();
console.log('EasyController加载中...');
console.log(`检测到EasyController存储位置:[${__dirname||'.'}/${__filename}]`);
console.log('[EasyController]整理文件中...');
console.log('[EasyController]文件:');
/**
* @param {Box3AssetListEntry[]} asts
*/
function dir(asts,deep){
for(const ast of asts){
var log='';
for(let i=1;i<=deep;i++)log+='····';
console.log(`${log}[${assetTypes[ast.type]}]${ast.path.split('/').pop()}`);
if(ast.type==Box3AssetType.DIRECTORY)dir(resources.ls(ast.path),deep+1);
}
}
dir(resources.ls('.'),1);
}();
//tools
function getFileName(){
try{
throw Error();
}catch(err){
return err.stack.split('\n').
find(x=>x.includes('eval')).slice(13).split(':')[0];
}
}
function getLine(){
try{
throw Error();
}catch(err){
return err.stack.split('\n').
find(x=>x.includes('eval')).slice(13).split(':')[1];
}
}
//logger
class Logger{
/**
* 为每个文件建立独立对话框
* @param {boolean?} showLine 是否显示输出的行数,默认为false
* @param {boolean?} showTime 是否显示输出的时间,默认为false
*/
constructor(showLine,showTime){
this.filename=getFileName();
this.showLine=showLine||false;
this.showTime=showTime||false;
this.log(`[logger] ${this.filename}logger加载完毕`);
}
get preLog(){
var log='';
var d=new Date();
if(this.showTime)log+=`[${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}]`;
log+='['+this.filename;
if(this.showLine)log+=':'+getLine();
return log+']';
}
log(...args){
return console.log(this.preLog,...args);
}
warn(...args){
return console.warn(this.preLog,...args);
}
error(...args){
return console.error(this.preLog,...args);
}
clear(){
console.clear();
console.log(`clear at ${this.preLog}`);
}
}
//exports
module.exports={
Logger,
}点赞0
评论