Luacom 使用中文文件名 (Lua Unicode UTF-8)

来源: http://hi.baidu.com/nivrrex/blog/item/17c231adad9e8a0f4b36d6ca.html/cmtid/ccfc7bcbaa7d6012be09e61b

 

Luacom内部使用的应该是UTF-8编码
所以直接使用ANSI编码的中文文件名,会打不开
研究了几天,写了一个ANSI <-> UNICODE <-> UTF-8的lua扩展,以便使用
基本上应该还可以用(-_-|)
(链接中的永硕网盘提供相应的Unicode.dll下载)

更新历史:
     2008-11-3 修正getallfilews函数使用内存浪费问题(分配内存时多分配了1倍)。将wchar_t和char 的大小比值2定义为CHAR_SCALE。getallfilews和getallfilewc返回值最后添加L"/0"。
     2008-11-2 将部分函数提取出来,以便重复使用。更改getallfilew为getallfilewc,添加getallfilews函数,区别是一个为fgetwc实现,一个是fgetws实现,后者速度为前者3-4倍。
     2008-11-1 增加getallfilew和getfilesizew,分别为读取一个Unicode编码文件和一个获取文件大   小的函数
     2008-10-28 修复bug,原因为char 和 wchar_t 类型的问题(汗一个)
     2008-10-27 初次版本,存在bug,调用多次函数后,出现代码崩溃现象(PS:目前测试代码正常,但     如果在调用oExcel.WorkBooks:Open前使用print(a2u8("C://哈哈.xls"))做实验的话,会导致代码失败 ,    慢慢查找原因吧-_-||| 。是C代码内存泄漏?还是Lua 堆栈问题?)

C代码如下:

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <windows.h>

#define BUFF_SIZE 1024
#define CHAR_SCALE (sizeof(wchar_t)/sizeof(char))

wchar_t * AToU( const char* str )
{
     int       textlen ;
     wchar_t * result;
     textlen = MultiByteToWideChar( CP_ACP, 0, str,- 1,       NULL, 0 );
     result = ( wchar_t *)malloc((textlen+ 1)* sizeof( wchar_t));
     memset(result, 0,(textlen+ 1)* sizeof( wchar_t));
     MultiByteToWideChar(CP_ACP, 0,str,- 1,(LPWSTR)result,textlen );
     return       result;
}
char * UToA( const wchar_t *str )
{
     char * result;
     int textlen;
     // wide char to multi char
     textlen = WideCharToMultiByte( CP_ACP,       0,       str,       - 1,       NULL, 0, NULL,   NULL    );
     result =( char *)malloc((textlen+ 1)* sizeof( char));
     memset( result, 0, sizeof( char) * ( textlen + 1 ) );
     WideCharToMultiByte( CP_ACP, 0, str, - 1, result, textlen, NULL, NULL );
     return result;
}
wchar_t * U8ToU( const char* str )
{
     int       textlen ;
     wchar_t * result;
     textlen = MultiByteToWideChar( CP_UTF8, 0, str,- 1,       NULL, 0 );
     result = ( wchar_t *)malloc((textlen+ 1)* sizeof( wchar_t));
     memset(result, 0,(textlen+ 1)* sizeof( wchar_t));
     MultiByteToWideChar(CP_UTF8, 0,str,- 1,(LPWSTR)result,textlen );
     return       result;
}
char * UToU8( const wchar_t *str )
{
     char * result;
     int textlen;
     // wide char to multi char
     textlen = WideCharToMultiByte( CP_UTF8,       0,       str,       - 1,       NULL, 0, NULL,   NULL    );
     result =( char *)malloc((textlen+ 1)* sizeof( char));
     memset(result, 0, sizeof( char) * ( textlen + 1 ) );
     WideCharToMultiByte( CP_UTF8, 0, str, - 1, result, textlen, NULL, NULL );
     return result;
}

static int Unicode_a2u(lua_State *L)
{
     const char* str;
     wchar_t* result;
     /*传递第一个参数*/
     str = lua_tostring(L, - 1);
     /*开始转换*/
     result = AToU(str);
     /*返回值,*/
     lua_pushlstring(L, ( char*)result,wcslen(result)*CHAR_SCALE);
     return 1;
}

static int Unicode_u2a(lua_State *L)
{
     const wchar_t* str;
     char* result;
     /*传递第一个参数*/
     str = ( wchar_t *)lua_tostring(L, - 1);
     /*开始转换*/
     result = UToA(str);
     /*返回值,*/
     lua_pushstring(L, result);
     return 1;
}

static int Unicode_u2u8(lua_State *L)
{
     const wchar_t* str;
     char* result;
     /*传递第一个参数*/
     str = ( wchar_t*)lua_tostring(L, - 1);
     /*开始转换*/
     result = UToU8(str);
     /*返回值,*/
     lua_pushstring(L, result);
     return 1;
}

static int Unicode_u82u(lua_State *L)
{
     const char* str;
     wchar_t * result;
     /*传递第一个参数*/
     str = lua_tostring(L, - 1);
     /*开始转换*/
     result = U8ToU(str);
     /*返回值,*/
     lua_pushlstring(L, ( char*)result,wcslen(result)*CHAR_SCALE);
     return 1;
}

static int Unicode_a2u8(lua_State *L)
{
     const char* str;
     wchar_t * temp;
     char* result;
     /*传递第一个参数*/
     str = lua_tostring(L, - 1);
     /*开始转换*/
     temp = AToU(str);
     result = UToU8(temp);
     /*返回值,*/
     lua_pushstring(L, result);
     return 1;
}

static int Unicode_u82a(lua_State *L)
{
     const char* str;
     wchar_t * temp;
     char* result;
     /*传递第一个参数*/
     str = lua_tostring(L, - 1);
     /*开始转换*/
     temp = U8ToU(str);
     result = UToA(temp);
     /*返回值,*/
     lua_pushstring(L, result);
     return 1;
}
/*获取一个文件大小*/
static int _GetFileSize( const char* filename)
{
     long len;
     FILE * fp;
     /*用只读打开文件并seek到文件末尾的方式获取文件大小*/
     if ((fp = fopen(filename, "r")) == NULL)
     {
         printf( "%s is not invalid /n ",filename);
         return 0;
     }
     fseek(fp, 0, SEEK_END);
     len = ftell(fp);
     fclose(fp);
     return len;
}
/*Lua 获取 文件大小*/
static int GetFileSizeW(lua_State *L)
{
     /*传递第一个参数,文件名*/
     const char* filename = lua_tostring(L, - 1);
     lua_pushinteger(L, _GetFileSize(filename));
     return 1;
}

/*读取一个Unicode文件,使用fgetwc函数,IO导致速度较慢*/
static int GetAllFileWC(lua_State *L)
{
     /*传递第一个参数,文件名*/
     const char* filename = lua_tostring(L, - 1);
     /*获取文件大小*/
     int len;
     len = _GetFileSize(filename);
     /*设置缓存大小*/
     wchar_t * buf;
     /*由于wchar_t长度为char长度一倍,所以buf空间大小为文件长度一半,再加末尾的 '/0'*/
     buf = ( wchar_t *) malloc ( sizeof( wchar_t) * (len/CHAR_SCALE+ 1));

     int i = 0 ;
     FILE*      input=fopen( filename, "rb");
     while(!feof(input))
     {
         buf[i++]=fgetwc(input);
     }
     /*字符串末尾置零*/
     buf[i- 1]= L'/0';
     lua_pushlstring(L, ( char*)buf,wcslen(buf)*CHAR_SCALE);
     return 1;
}
/*读取一个Unicode文件,使用fgetws函数,速度较快*/
static int GetAllFileWS(lua_State *L)
{
     /*传递第一个参数,文件名*/
     const char* filename = lua_tostring(L, - 1);
     /*获取文件大小*/
     FILE*     input=fopen( filename, "rb");
     int len = _GetFileSize(filename);
     /*初始化变量*/
     wchar_t *all ;
     all = ( wchar_t *)malloc( sizeof( wchar_t)*(len/CHAR_SCALE+ 1));
     memset(all, 0, sizeof( wchar_t) * (len/CHAR_SCALE+ 1) );

     int i= 0;
     while(!feof(input))
     {
         wchar_t *    buf;
         buf = ( wchar_t *)malloc( sizeof( wchar_t)*BUFF_SIZE)          ;
         memset(buf,    0, sizeof( wchar_t) * BUFF_SIZE );

         int j= 0;
         fgetws(buf,    BUFF_SIZE,    input);
         /*连接缓存空间,原先使用wcscat连接,但是很慢且有问题,使用指针后速度很快*/
         while(buf[j] != L'/0')
         {
             all[i++]=buf[j++];
         }
         free(buf);
     }
     all[len/CHAR_SCALE]= L'/0';
     lua_pushlstring(L, ( char*)all,wcslen(all)*CHAR_SCALE);
     return 1;
}

static const luaL_reg UnicodeFunctions [] =
{
     { "a2u",Unicode_a2u},
     { "u2a",Unicode_u2a},
     { "u2u8",Unicode_u2u8},
     { "u82u",Unicode_u82u},
     { "a2u8",Unicode_a2u8},
     { "u82a",Unicode_u82a},
     { "getfilesizew",GetFileSizeW},
     { "getallfilewc",GetAllFileWC},
     { "getallfilews",GetAllFileWS},
     {NULL, NULL}
};

int __cdecl __declspec(dllexport) luaopen_Unicode(lua_State* L)
{
     luaL_openlib(L, "Unicode", UnicodeFunctions, 0);
     return 1;
}


Lua调用代码如下:

--假定dll文件位于C:/Unicode.dll
--假定中文路径的文件名为C:/哈哈.xls
--假定C:/Unicode.csv为一个UTF-16LE编码文件
require " luacom"
local unicode = package.loadlib( " C: // Unicode.dll", " luaopen_Unicode")

if(unicode) then
    unicode()
    print( " OK!")
else
    print( " Not found!")
    -- Error
end

a2u =Unicode.a2u
u2a =Unicode.u2a
u2u8 =Unicode.u2u8
u82u =Unicode.u82u
u82a =Unicode.u82a
a2u8 =Unicode.a2u8
getallfilewc = Unicode.getallfilewc
getallfilews = Unicode.getallfilews
getfilesizew= Unicode.getfilesizew

print(getfilesizew( " C: // Unicode.csv"))

local x = os.clock()
getallfilewc( " C: // Unicode.csv")
print(string.format( " elapsed time: %.2f /n ",os.clock() - x ))
local x = os.clock()
getallfilews( " C: // Unicode.csv")
print(string.format( " elapsed time: %.2f /n ",os.clock() - x ))

print(a2u8( " 哈哈.xls"))

local oExcel = luacom.CreateObject( " Excel.Application")
if oExcel == nil then error( " Object is not create") end
oExcel.Visible = 1
oExcel.WorkBooks:Open(a2u8( " C: // 哈哈.xls"), nil, 0)
oExcel.ActiveWorkbook.Sheets( 1):Select()

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值