标题:求教:假设文件名是这么一个名字,VFP有没办法打开并读出该文件的内容?
只看楼主
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:29
帖 子:484
专家分:1827
注 册:2018-3-13
得分:0 
以下是引用吹水佬在2022-11-11 23:02:30的发言:
s = FILETOSTR("d:\temp\?眍.txt")

vfp里面能输入䁖字?
2022-11-11 23:11
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:29
帖 子:484
专家分:1827
注 册:2018-3-13
得分:0 
唉,原来只是长得一样,不是一回事儿


[此贴子已经被作者于2022-11-11 23:19编辑过]

2022-11-11 23:16
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
撞衫
内码有明示
2022-11-12 05:21
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
大佬们啊,歪楼啦!楼歪啦!
请用代码读写本帖附件的几个文件试试:

UTF-8.rar (1.49 KB)


可能楼主在顶楼说得啰哩啰嗦,没说到点子上。
楼主想讨论的是:
若不幸遇上了Unicode文件名,在VFP中应如何读、写这些文件(假设是TXT,只负责读取或写入,而不负责显示文档具体内容)?

以下是引用吹水佬在2022-11-11 23:02:30的发言:

确是,只复制文件名有VFP查看不对的,VFP不支持UNICODE
从文件里取出看是对的。

FOR i=1 TO ADIR(arr,"d:\temp\*.txt")
    ? arr,STRCONV(arr,15)
ENDFOR
s = FILETOSTR("d:\temp\?眍.txt")
?STRCONV(s,15)

2022-11-12 08:17
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用cssnet在2022-11-12 08:17:48的发言:

大佬们啊,歪楼啦!楼歪啦!
请用代码读写本帖附件的几个文件试试:



可能楼主在顶楼说得啰哩啰嗦,没说到点子上。
楼主想讨论的是:
若不幸遇上了Unicode文件名,在VFP中应如何读、写这些文件(假设是TXT,只负责读取或写入,而不负责显示文档具体内容)?

重要的要说3次...CMD


程序代码:
DECLARE long CreateProcess       IN kernel32 as apiCreateProcess       string@,string@,string@,string@,long,long,string@,string@,string@,string@
DECLARE long CloseHandle         IN kernel32 as apiCloseHandle         long
DECLARE long WaitForSingleObject IN kernel32 as apiWaitForSingleObject long,long
DECLARE long CreateFileW         IN kernel32 as apiCreateFileW         string,long,long,string@,long,long,long
DECLARE long GetFileSize         IN kernel32 as apiGetFileSize         long,long@
DECLARE long CloseHandle         IN kernel32 as apiCloseHandle         long
DECLARE long ReadFile            IN kernel32 as apiReadFile            long,string@,long,long@,string@
DECLARE long WriteFile           IN kernel32 as apiWriteFile           long,string@,long,long@,string@

#define CREATE_NO_WINDOW        0x08000000
#define GENERIC_READ            0x80000000
#define GENERIC_WRITE           0x40000000
#define FILE_SHARE_READ         1
#define FILE_SHARE_WRITE        2
#define FILE_ATTRIBUTE_NORMAL   0x80
#define CREATE_ALWAYS           2
#define OPEN_EXISTING           3
#define INVALID_HANDLE_VALUE    -1

** 路径
path = "d:\temp\UTF8\"
ftmp = path + "tmp\tmp.tmp"    && 临时文件

** 获取文件名
IF FILE(ftmp)
    DELETE FILE (ftmp)
ENDIF
cmd = "cmd /U /C dir /B " + path + "*.txt > " + ftmp
IF !CreateProc(cmd)
    RETURN .f.
ENDIF

** 遍历文件读写
s = FILETOSTR(ftmp)
i = 1
n = 1
len = AT(0h0D000A00,s,i)
DO WHILE len != 0
        ** 输入/输出文件名
    fn = SUBSTR(s,n,len-n)
    inFileName  = STRCONV(path,5)+fn+0h00
    outFileName = STRCONV(path+"tmp\",5)+fn+0h00
        ** 打开读文件
    hFileRead = myCreateFile(inFileName, 0)
    IF hFileRead == INVALID_HANDLE_VALUE
        RETURN .f.
    ENDIF
        ** 创建写文件
    hFileWrite = myCreateFile(outFileName, 1)
    IF hFileWrite == INVALID_HANDLE_VALUE
        apiCloseHandle(hFileRead)
        RETURN .f.
    ENDIF
        ** 读写文件
    nSize = apiGetFileSize(hFileRead, 0)        && 文件大小
    buf = SPACE(nSize)
    apiReadFile(hFileRead,  @buf,nSize,0,NULL)  && 读文件
    apiWriteFile(hFileWrite,@buf,nSize,0,NULL)  && 写文件
        ** 关闭文件
    apiCloseHandle(hFileRead)
    apiCloseHandle(hFileWrite)
        ** 下一个文件名位置
    i = i+1
    n = len + 4
    len = AT(0h0D000A00,s,i)
ENDDO
CLEAR ALL 
RETURN

** 调用 apiCreateFileW 打开/创建 文件
FUNCTION myCreateFile(fName, nFlag)
    LOCAL hFile
    IF nFlag == 0
        hFile = apiCreateFileW(fName, GENERIC_READ,  FILE_SHARE_READ,  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
    ELSE
        hFile = apiCreateFileW(fName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
    ENDIF
    RETURN hFile
ENDFUNC

** 阻塞式运行外部程序(同步)
FUNCTION CreateProc(cFileName, cParam)
    LOCAL si, pi
    si = BINTOC(68, "4RS") + REPLICATE(0h00, 64)    && STARTUPINFO 结构
    pi = REPLICATE(0h00, 16)                        && PROCESS_INFORMATION 结构
    IF apiCreateProcess(NULL,cmd,NULL,NULL,1,CREATE_NO_WINDOW,NULL,NULL,@si,@pi) == 0
        RETURN .f.
    ENDIF
    LOCAL hProcess, hThread, ret
    hProcess = CTOBIN(SUBSTR(pi, 1, 4), "4rs")
    hThread  = CTOBIN(SUBSTR(pi, 5, 4), "4rs")
    ret = apiWaitForSingleObject(hProcess, -1)
    apiCloseHandle(hProcess)
    apiCloseHandle(hThread)
    RETURN ret != -1
ENDFUNC

2022-11-12 12:07
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
因为担心可能弹出DOS小黑窗,不太敢用CMD啊!!!

以下是引用吹水佬在2022-11-12 12:07:11的发言:

重要的要说3次...CMD

2022-11-12 13:04
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:29
帖 子:484
专家分:1827
注 册:2018-3-13
得分:0 
来个不使用 cmd 命令的
程序代码:
Local oShell as Shell.Application
Local oFolder, oFile, nCP, cPath, cFile, cMsg

Create cursor test ( ;
     path W ;        && 存放 utf-8 格式的路径名
    ,file W ;        && 存放 utf-8 格式的文件名
    ,data W ;        && 存放文件 raw 内容
)

*/// GetDir 是 vfp 原生函数, 别指定带 unicode 编码的路径 ///
m.cPath = GetDir('', 0h0d0a+'指定要读取的 unicode 文件所在文件夹', '',64)
*-- m.cPath = 'D:\UTF-8'
m.cPath = Addbs(m.cPath)

*/// 不熟悉 vfp 实现需要结构的 win32 函数(FindFirstFile, FindNextFile, ...),用外壳对象偷懒实现 ///
*-- 循环读取指定文件夹下所有文件的内容, 保存到 test 游标
m.nCP = Sys(3101, 65001)        && 临时使用 utf-8 格式与 COM 交换数据
m.oShell = NewObject('Shell.Application')
m.oFolder = m.oShell.NameSpace(m.cPath)
For each m.oFile in m.oFolder.Items
    Insert into test (path, file) Values (Strconv(m.cPath,9), m.oFile.name)
    m.cFile = Strconv(path + file, 12)
    Replace next 1 data with FileToStrW(m.cFile)
EndFor
Sys(3101, m.nCP)                && 恢复现场

*-- 显示读取的: 文件名    文件内容
Declare Long MessageBoxW in win32api Long, String, String, Long
m.cMsg = ''
Scan all
    m.cMsg = m.cMsg + Strconv(file,12) + 0h09000900 + Strconv(data,12) + 0h0d000a00
EndScan
MessageBoxW(0, m.cMsg+0h0000, '', 0)

*-- 变体版 FileToStr - 文件名必须是 utf-16 编码
Function FileToStrW(tcFile)
    Local hFile, nLen, nRead, nResult
    m.hFile = CreateFileW(m.tcFile+0h0000, 0x80000000,1,0,3,0x80,0)        && 偷懒, 没用编译时常量
    If m.hFile == -1
        Return ''
    EndIf
    m.nLen = GetFileSize(m.hFile, 0)
    If m.nLen < 1
        m.nResult = 0
    Else
        m.cRet = Replicate(0h00, m.nLen)
        m.nRead = 0
        m.nResult = ReadFile(m.hFile, @ m.cRet, m.nLen, @ m.nRead, 0)
    EndIf
    CloseHandle(m.hFile)
    Return Iif(m.nResult == 0, '', Left(m.cRet, m.nRead))
EndFunc

*-- win32api functions
Function CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes ;
        , dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
    Declare Long CreateFileW in win32api String, Long, Long, Long, Long, Long, Long
    Return CreateFileW(m.lpFileName, m.dwDesiredAccess, m.dwShareMode, m.lpSecurityAttributes ;
        , m.dwCreationDisposition, m.dwFlagsAndAttributes, m.hTemplateFile)
EndFunc
Function ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped)
    Declare Long ReadFile in win32api Long, String @, Long, Long @, Long
    Return ReadFile(m.hFile, @ m.lpBuffer, m.nNumberOfBytesToRead ;
        , @ m.lpNumberOfBytesRead, m.lpOverlapped)
EndFunc
Function GetFileSize(hFile, lpFileSizeHigh)
    Declare Long GetFileSize in win32api Long, Long @
    Return GetFileSize(m.hFile, @ m.lpFileSizeHigh)
EndFunc
Function CloseHandle(hObject)
    Declare Long CloseHandle in win32api Long
    Return CloseHandle(m.hObject)
EndFunc


[此贴子已经被作者于2022-11-13 15:19编辑过]

2022-11-13 14:59
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
非常感谢!好好学习一下。

以下是引用csyx在2022-11-13 14:59:40的发言:
来个不使用 cmd 命令的...

2022-11-13 21:36
schtg
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:https://t.me/pump_upp
等 级:贵宾
威 望:67
帖 子:1355
专家分:2534
注 册:2012-2-29
得分:0 
谢谢楼上两位版主!
2022-11-14 06:00
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
讲真,不太熟悉WinAPI的Unicode宽字符函数,这倒是吹版“VFP结构类型”应用的极好场合!
不知路过的大侠能否写一个不用“外壳对象”,改用“需要结构的 win32 函数(FindFirstFile, FindNextFile, ...)”的实现范例?
非常感谢关注与帮助!

以下是引用csyx在2022-11-13 14:59:40的发言:

*/// 不熟悉 vfp 实现需要结构的 win32 函数(FindFirstFile, FindNextFile, ...),用外壳对象偷懒实现 ///

2022-11-16 13:38



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-510613-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030515 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved