Cocos-lua / Quick 使用io.open方法时路径问题

本文详细介绍了在Cocos-Lua或Quick框架下,如何使用io.open进行文件操作,包括不同模式的使用场景及注意事项,特别强调了跨平台路径获取的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

情景:在Cocos—lua或者Quick框架下使用io.open进行文件操作

 

io.open使用方法介绍:

io.open (fn [, m]) 打开文件,返回文件句柄,fn文件名,m模式有:

r 以只读方式打开文件,该文件必须存在。

w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)

r+ 以可读写方式打开文件,该文件必须存在。

w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a+ 与a类似,但此文件可读可写

二进制模式,如果文件是二进制文件,可以加上b

号表示对文件既可以读也可以写

 

因为游戏的运行平台可能是win32,安卓,ios等,所以io.open的第一个参数不能使用绝对路径

可以使用cc.FileUtils:getInstance():getWritablePath()接口获取本地路径

local path = cc.FileUtils:getInstance():getWritablePath()
local file = io.open(path .. "test.txt","w+")

 

--------- beginning of system --------- beginning of main 2025-07-15 15:26:27.829 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082da 2025-07-15 15:26:27.829 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082e5 2025-07-15 15:26:27.835 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x00008c29 2025-07-15 15:26:27.835 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000087fe 2025-07-15 15:26:27.858 3124-3153 EGL_emulation org.cocos2d.demo E tid 3153: eglSurfaceAttrib(1493): error 0x3009 (EGL_BAD_MATCH) 2025-07-15 15:26:29.679 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::onGetStringFromFile stream not found, possible missing file. 2025-07-15 15:26:29.679 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::runScript script stream, buffer is empty! 2025-07-15 15:26:29.679 3124-3151 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:26:29.718 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::evalString catch exception: 2025-07-15 15:26:29.737 3124-3151 jswrapper org.cocos2d.demo E ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 STACK: [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.2 2025-07-15 15:26:29.738 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::evalString script src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js, failed! 2025-07-15 15:26:29.738 3124-3151 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:26:42.981 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:26:42.981 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:26:42.989 1452-1763 OMXNodeInstance media.codec E setConfig(0xf5210060:google.mp3.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) 2025-07-15 15:26:42.990 1452-1763 OMXNodeInstance media.codec E getConfig(0xf5210060:google.mp3.decoder, ConfigAndroidVendorExtension(0x6f100004)) ERROR: Undefined(0x80001001) self问题解决了吗
最新发布
07-16
<think>根据日志,问题出现在加载重力引擎SDK,错误信息为“Uncaught ReferenceError: self is not defined”。这是因为在原生环境中(如Android或iOS),`self`对象可能未被定义。`self`通常用于Web Worker中,在浏览器中指向全局对象(window),但在原生环境中不存在。 解决方案: 1. 在加载重力引擎SDK之前,确保全局对象中存在`self`。如果不存在,将`self`指向全局对象(在原生环境中,全局对象可能是`global`或`this`)。 2. 修改环境修复部分,确保在加载任何脚本之前,已经定义了`self`。 我们在环境修复部分已经做了全局对象的修复,但可能还需要针对`self`进行特殊处理。因此,我们可以在环境修复代码中添加对`self`的修复。 修改后的环境修复代码: ```javascript // ====== 环境修复与全局对象安全 ====== (function() { // 确保全局对象存在 const getGlobalObject = () => { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')() || {}; }; const globalObj = getGlobalObject(); // 修复全局变量 if (typeof global === 'undefined') global = globalObj; if (typeof self === 'undefined') self = globalObj; // 确保self存在 if (typeof globalThis === 'undefined') globalThis = globalObj; // 确保require函数存在(关键修复) if (typeof globalObj.require === 'undefined') { globalObj.require = function(module) { // 简单实现require功能 if (globalObj.__modules && globalObj.__modules[module]) { return globalObj.__modules[module]; } console.warn(`[RequireFallback] Module '${module}' not found`); return {}; }; console.log('[EnvFix] Created fallback require function'); } })(); ``` 关键修改:在环境修复中,如果`self`未定义,则将其赋值为`globalObj`(即全局对象)。这样在后续执行中,`self`就会被定义。 另外,日志中还显示了一个错误:`ScriptEngine::onGetStringFromFile stream not found, possible missing file.`,这可能是由于文件路径问题导致加载失败。我们已经提供了多个路径尝试,但需要确保在原生平台中,路径是相对于项目根目录的。 由于原生平台的文件系统与Web不同,我们可能需要调整SDK的加载路径。在原生平台中,脚本通常位于`src`目录下,但构建后会被打包到特定位置。因此,我们可能需要使用绝对路径或调整路径策略。 但是,由于Cocos Creator在构建会处理资源路径,我们可以尝试使用`cc.assetManager`的加载机制,它已经处理了平台差异。然而,在入口阶段,`cc.assetManager`可能还未完全初始化。因此,我们采用备用方案:在原生平台使用相对路径(相对于应用程序的根目录)加载。 由于我们无法确定原生平台的确切路径,我们可以尝试以下策略: - 在原生平台,使用绝对路径`/src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js`(注意:在Android上,assets文件位于assets目录,但构建后会被压缩,所以不能直接使用文件路径- 或者,将SDK文件作为项目资源,通过Cocos的资源加载机制加载(但入口阶段可能无法使用) 考虑到问题的复杂性,我们可以在原生平台使用`cc.assetManager`加载(如果可用),否则使用备用路径。 修改`loadScript`函数,在原生平台使用`cc.assetManager.loadScript`,并调整路径为相对路径。 但是,从日志看,错误发生在加载SDK脚本,因此我们还需要确保在加载SDK之前,环境修复(包括定义`self`)已经完成。 因此,我们调整代码执行顺序: 1. 环境修复(包括定义`self`) 2. 引擎初始化检测 3. 加载SDK(在加载SDK之前,环境修复已经完成) 我们已经这样做了,所以现在主要是修复`self`的问题。 如果问题仍然存在,可能是由于重力引擎的SDK内部使用了`self`,而我们的修复在SDK加载之后才执行?但我们的环境修复是立即执行的,所以应该是在SDK加载之前就完成了。 因此,我们只需要在环境修复中确保`self`被定义即可。 另外,日志中还有一条错误:`eglSurfaceAttrib(1493): error 0x3009 (EGL_BAD_MATCH)`,这是OpenGL相关的错误,通常与渲染设置有关,但不影响程序逻辑,可以暂忽略。 综上所述,我们主要修复`self`未定义的问题,通过环境修复代码确保`self`存在。 修改后的代码已在环境修复部分添加了`self`的定义。请使用修改后的环境修复代码重新运行。 如果问题仍然存在,我们可以尝试在加载SDK之前再次检查并修复`self`,但环境修复代码已经是最先执行的,所以应该没有问题。 注意:在原生平台,全局对象可能是`global`,而我们的环境修复已经将`self`指向了`global`,这样在SDK中使用`self`,实际上就是`global`,从而避免了未定义的错误。 让我们重新生成完整代码,并确保环境修复部分包含对`self`的修复。</think>### 解决 `self is not defined` 错误 根据您提供的日志,问题出在重力引擎 SDK 中引用了未定义的 `self` 对象。这通常在原生平台(Android/iOS)中出现,因为浏览器环境中的 `self` 对象在原生环境中不可用。以下是完整的解决方案: ```javascript // ====== 环境修复与全局对象安全 ====== (function() { // 确保全局对象存在 const getGlobalObject = () => { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')() || {}; }; const globalObj = getGlobalObject(); // 修复全局变量 if (typeof global === 'undefined') global = globalObj; if (typeof self === 'undefined') self = globalObj; // 关键修复:确保 self 存在 if (typeof globalThis === 'undefined') globalThis = globalObj; // 确保 require 函数存在 if (typeof globalObj.require === 'undefined') { globalObj.require = function(module) { if (globalObj.__modules && globalObj.__modules[module]) { return globalObj.__modules[module]; } console.warn(`[RequireFallback] Module '${module}' not found`); return {}; }; console.log('[EnvFix] Created fallback require function'); } // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 原生平台需要定义 self 和 window if (typeof window === 'undefined') window = globalObj; if (typeof self === 'undefined') self = globalObj; // 解决原生平台的 XMLHttpRequest 问题 if (typeof XMLHttpRequest === 'undefined') { XMLHttpRequest = function() { return cc.loader.getXMLHttpRequest(); }; } console.log('[EnvFix] Native environment patched'); } })(); // ====== 引擎初始化保护系统 ====== const EngineReady = (function() { // ...(保持原有引擎初始化代码不变)... })(); EngineReady.init(); // ====== 游戏主入口 ====== async function gameMainEntry() { // ...(保持原有主入口代码不变)... } // ====== SDK加载器 ====== async function loadGravityEngineSDK() { // 使用相对路径解决加载问题 const sdkPaths = [ './assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js', '_plugs/lib/gravityengine.mg.cocoscreator.min.js', 'lib/gravityengine.mg.cocoscreator.min.js' ]; for (const path of sdkPaths) { try { await loadScript(path); console.log('[SDK] Loaded from:', path); // 关键修复:确保 SDK 加载后 self 仍然存在 if (typeof self === 'undefined') { console.warn('[SDK] Self is undefined after loading, patching...'); const globalObj = getGlobalObject(); self = globalObj; window = globalObj; } initGravityEngine(); return; } catch (e) { console.warn('[SDK] Load failed:', path, e.message); } } console.error('[SDK] All paths failed'); handleSDKLoadFailure(); } function loadScript(path) { return new Promise((resolve, reject) => { // 优先使用Cocos的加载系统 if (cc.assetManager?.loadScript) { cc.assetManager.loadScript(path, (err) => { if (err) { // 原生平台特殊处理 if (cc.sys.isNative) { console.warn('[SDK] Using native fallback for script loading'); try { // 原生平台直接执行脚本 const jsb = cc.sys.__globalAdapter; if (jsb && jsb.require) { jsb.require(path); return resolve(); } } catch (nativeError) { console.error('[SDK] Native require failed:', nativeError); } } reject(err); } else { resolve(); } }); return; } // 后备方案:直接创建script标签 try { const script = document.createElement('script'); script.src = path; script.onload = resolve; script.onerror = () => reject(new Error(`Failed to load ${path}`)); document.head.appendChild(script); console.warn('[SDK] Using DOM fallback for script loading'); } catch (e) { reject(e); } }); } function initGravityEngine() { if (typeof GravityEngine !== 'function') { console.error('[SDK] GravityEngine not found'); return; } try { // 使用您的AppID 624768904 GravityEngine.init({ appId: '624768904', enableLog: true }); console.log('[SDK] GravityEngine initialized with AppID 624768904'); } catch (e) { console.error('[SDK] Init failed:', e); } } // ...(其余代码保持不变)... ``` ### 关键修复点 1. **全局 self 对象修复**: ```javascript // 确保 self 在所有环境中都存在 if (typeof self === 'undefined') self = globalObj; // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { if (typeof window === 'undefined') window = globalObj; if (typeof self === 'undefined') self = globalObj; } ``` 2. **SDK 加载后二次检查**: ```javascript // 加载 SDK 后再次确保 self 存在 await loadScript(path); if (typeof self === 'undefined') { console.warn('[SDK] Self is undefined after loading, patching...'); const globalObj = getGlobalObject(); self = globalObj; window = globalObj; } ``` 3. **原生平台特殊处理**: ```javascript // 原生平台的 XMLHttpRequest 修复 if (typeof XMLHttpRequest === 'undefined') { XMLHttpRequest = function() { return cc.loader.getXMLHttpRequest(); }; } // 原生平台的脚本加载 if (cc.sys.isNative) { const jsb = cc.sys.__globalAdapter; if (jsb && jsb.require) { jsb.require(path); return resolve(); } } ``` 4. **全局对象获取函数**: ```javascript // 安全获取全局对象的函数 const getGlobalObject = () => { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')() || {}; }; ``` ### 错误分析与解决方案 根据您的错误日志: ``` ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 ``` 问题分析: 1. **环境差异**:重力引擎 SDK 在浏览器中运行正常,但在原生平台(Android/iOS)中失败 2. **原因**:SDK 内部使用了 `self` 对象,这在浏览器中指向 `window`,但在原生平台中未定义 3. **根本原因**:Cocos Creator 的原生环境没有完整的浏览器 API 解决方案: 1. **全局对象修复**:确保所有环境中都存在 `self` 和 `window` 对象 2. **加载后检查**:在 SDK 加载后再次检查并修复全局对象 3. **原生平台特殊处理**:针对 Android/iOS 平台添加额外的环境修复 4. **XMLHttpRequest 修复**:解决 SDK 可能需要的网络请求功能 ### 完整实施步骤 1. **替换入口文件**: - 将上述完整代码复制到项目入口文件(如 `main.js`) - 确保重力引擎文件位于 `assets/_plugs/lib/` 目录 2. **清理构建缓存**: ```bash rm -rf build/ temp/ library/ ``` 3. **构建项目**: -Cocos Creator 中选择正确的构建平台 - 执行构建操作 4. **测试验证**: - 在 Android 设备上安装并运行应用 - 检查日志中是否还有 `self is not defined` 错误 - 验证重力引擎是否成功初始化 ### 备用方案 如果问题仍然存在,可以在 SDK 加载前添加以下代码: ```javascript // 在加载重力引擎之前添加此代码 if (typeof self === 'undefined') { console.warn('[Pre-SDK] Self is undefined, creating fallback'); const globalObj = Function('return this')() || {}; self = globalObj; window = globalObj; globalThis = globalObj; // 确保基本浏览器API存在 if (typeof document === 'undefined') { document = { createElement: () => ({ appendChild: () => {} }), head: { appendChild: () => {} } }; } } ``` 这个方案确保即使环境修复未能完全解决问题,SDK 加载前也能创建必要的全局对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值