FtpFindFirstFile()及InternetFindNextFile()对汉字编码的支持问题

首先说明情况。

ftp服务器是同事写的,运行在linux下,字符采用utf-8编码。

我写客户端,在windows下,自己的开发电脑是win74 64位简体中文版,ide采用vs2010,工程为ocx项目,支持MFC,unicode支持。


附加信息:

由于用到了字符编码的转换,为了简单,直接从网上找了相关的函数,参考网址:

http://blog.csdn.net/feisy/article/details/16826873

用到的函数名 Utf82Unicode()


服务器端的文件名如下(每种只列出了一个用于说明问题即可):

测C10001...

测333333...

测222222...

测B00005...


每个文件名都只列出了开头的字符,后面的没有再列出来了,因为本文要说的就是最前面的那个汉字“测”

程序步骤如下:

WIN32_FIND_DATAA wfd;
m_hFile = FtpFindFirstFile(cnn, lpFileName, &wfd, INTERNET_FLAG_NEED_FILE, 0);
... // 这里取wfd的文件名
BOOL bRet = InternetFindNextFile(m_hFile, &wfd);
while(bRet)
{
... // 这里检查wfd中的文件名
bRet = InternetFindNextFile(m_hFile, &wfd);
}

以上仅是流程说明问题,实际代码中是要获取wfd中的文件名然后进行对比,看是否是要搜索的文件名。

针对以上列出的4个文件名,wfd.cFileName得到的结果是不一样的,按照以上的顺序分别如下(16进制,内存):

内存                                                                        Utf82Unicode() 转换之后

34 5a 65 5a 31 00 30 00 30 00 30 00 31 00...       测C10001...

34 5a 3f 00 33 00 33 00 33 00 33 00 33 00...        ??33333...

34 5a 3f 00 32 00 32 00 32 00 32 00 32 00...        ??22222...

34 5a 64 5a 30 00 30 00 30 00 30 00 35 00...       测B00005...

注:以上的Utf82Unicode() 转换之前,需要先把unicode转换成ascii:

USES_CONVERSION;

char *p1 = W2A(wfd.cFileName);

TCHAR p2[1024];

memset(p2, 0, sizeof(p2));

Utf82Unicode(p1, p2);

CString strText = p2;

这里的strText就是最后得到的实际要用的字符串,正常的unicode字符串

转换之后有问题的两个字符“??”,其16进制的内存为:fd ff 3f

从以上转换之后的内容看,两个“??”占去了其后的一个字符,导致后面只有5个3和5个2,而不是原始的6个3和6个2

参数whireshink抓包查看,底层收到的数据,开头都是e6 b5 8b,这个是没错的。


从上面的cFileName内存看,字母的没错,但是数字的就变成了3f,而不是像字母那个是 字母+5a 的形式,不知道这api是如何转换的。

实际没办法,就试一下非unicode版本的api:

WIN32_FIND_DATA wfd;
m_hFile = FtpFindFirstFileA(cnn, lpFileName, &wfd, INTERNET_FLAG_NEED_FILE, 0);
... // 这里取wfd的文件名
BOOL bRet = InternetFindNextFileA(m_hFile, &wfd);
while(bRet)
{
... // 这里检查wfd中的文件名
bRet = InternetFindNextFileA(m_hFile, &wfd);
}

这次由于不是unicode版本,所以后面转换就少了一个步骤:

char *p1 = wfd.cFileName;

TCHAR p2[1024];

memset(p2, 0, sizeof(p2));

Utf82Unicode(p1, p2);

CString strText = p2;

这次再看strText,就是正确的了。


总结:

windows api内部的一些编码转换有bug,所以当有问题的时候,个版本的api试试说不定就能解决问题了


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 VB.NET 中,FtpFindFirstFile 函数用于在 FTP 服务器上查找第一个文件或目录。 以下是一个示例代码片段,演示如何使用 FtpFindFirstFile 函数: ```vb Imports System.Net Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim ftpRequest As FtpWebRequest = CType(WebRequest.Create("ftp://example.com/path"), FtpWebRequest) ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory ' 列出目录中的文件和目录 Dim ftpResponse As FtpWebResponse = CType(ftpRequest.GetResponse(), FtpWebResponse) Dim ftpStream As Stream = ftpResponse.GetResponseStream() Dim reader As New StreamReader(ftpStream) Dim fileNames As New List(Of String)() While Not reader.EndOfStream Dim fileName As String = reader.ReadLine() fileNames.Add(fileName) End While reader.Close() ftpStream.Close() ftpResponse.Close() For Each fileName As String In fileNames MessageBox.Show("文件名: " & fileName) Next End Sub End Class ``` 在上面的示例中,我们首先创建一个 FtpWebRequest 对象,并指定要连接的 FTP 服务器和路径。然后,我们将方法设置为 WebRequestMethods.Ftp.ListDirectory,以列出指定路径中的文件和目录。 接下来,我们发送 FTP 请求并获取响应。通过获取响应流,并使用 StreamReader 读取流中的内容,我们可以获取服务器上的文件和目录列表。 最后,我们将文件名存储在一个列表中,并在消息框中显示每个文件名。 请注意,上述示例仅列出了文件和目录的名称。如果您需要获取更多的文件信息,如大小、创建日期等,您可以使用 FtpWebRequest 的其他属性和方法来实现。 希望这可以帮助到您!如果您有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值