FTP传文件中文乱码问题,求大神解决
delphi吧
全部回复
仅看楼主
level 5
随云home 楼主
服务器端接收的含中文的文件名,中文都是乱码,我用AnsiToUtf8,UTF8Decode,Utf8ToAnsi,UTF8Decode,UTF8Encode,AnsiString
这些函数都转换了也没有效果,不用函数也不行,其中UTF8Decode和Utf8ToAnsi不能传,会报错,我用的XE6,请问有大神遇到同样的问题了吗,怎么解决的?
2015年08月13日 03点08分 1
level 10
发送者必须传送
TNetEncoding.URL.Encode(文件名);
服务器收到后
文件名 ;= TNetEncoding.URL.Decode(FTP文件名);
2015年08月13日 03点08分 2
但是发送者是摄像机,配置好了的,我只能改服务器端,怎样才能支持中文
2015年08月13日 07点08分
level 10
怎么个乱码?
2015年08月13日 07点08分 3
文件名为'hello你好',接收到的文件名为helloä½ å¥½;图片没发出来,我可以加你qq问吗,大神。
2015年08月14日 06点08分
回复
����home
:不能
2015年08月17日 02点08分
level 1
具体情况也没看明白。
serv-u的记得有个ftp命令里,去掉 什么用utf-8编码接收文件路径和文件名来着
2015年08月13日 23点08分 4
是用代码写的,不是控件,也不是APP
2015年08月14日 06点08分
回复
����home
:自己写的ftp服务端?
2015年08月14日 06点08分
回复
����ǣ��blue
:嗯嗯
2015年08月14日 06点08分
回复
����home
:客户端需要跟服务端一致。只修改一端,没有另外一端的设置很难。以前用的udp传输
2015年08月14日 07点08分
level 5
随云home 楼主
有人没,我自己顶一下
2015年08月14日 06点08分 5
level 14
试试把string转为ansistring
2015年08月14日 07点08分 6
用ansistring()这个 没用,也是乱码
2015年08月14日 07点08分
回复
����home
:不要强制转换,是用函数转
2015年08月14日 08点08分
@xuchuantao17 大哥,string转换成ansistring的我只知道这个, 还有什么函数?
2015年08月14日 09点08分
level 14
{ AnsiString与WideString互相转换函数 }
function AnsiStringToWideString(Const s: AnsiString): WideString;
var
iLen: Integer;
sw: WideString;
begin
Result := '';
if Length(s) = 0 then
Exit;
iLen := MultiByteToWideChar(CP_ACP, 0, PAnsiChar(s), -1, nil, 0);
SetLength(sw, iLen - 1);
MultiByteToWideChar(CP_ACP, 0, PAnsiChar(s), -1, PWideChar(sw), iLen);
Result := sw;
end;
function WideStringToAnsiString(Const s: WideString): AnsiString;
var
iLen: Integer;
sa: AnsiString;
begin
Result := '';
if Length(s) = 0 then
Exit;
iLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(s), -1, nil, 0, nil, nil);
SetLength(sa, iLen - 1);
WideCharToMultiByte(CP_ACP, 0, PWideChar(s), -1, PAnsiChar(sa), iLen,
nil, nil);
Result := sa;
end;
{ UTF8与WideString互相转换函数 }
function UTF8StringToWideString(Const s: UTF8String): WideString;
var
iLen: Integer;
sw: WideString;
begin
Result := '';
if Length(s) = 0 then
Exit;
iLen := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(s), -1, nil, 0);
SetLength(sw, iLen);
MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(s), -1, PWideChar(sw), iLen);
Result := sw;
end;
function WideStringToUTF8String(Const s: WideString): UTF8String;
var
iLen: Integer;
su: UTF8String;
begin
Result := '';
if Length(s) = 0 then
Exit;
iLen := WideCharToMultiByte(CP_UTF8, 0, PWideChar(s), -1, nil, 0, nil, nil);
SetLength(su, iLen);
WideCharToMultiByte(CP_UTF8, 0, PWideChar(s), -1, PAnsiChar(su), iLen,
nil, nil);
Result := su;
end;
{ UTF8与AnsiString互相转换函数 }
function UTF8StringToAnsiString(Const s: UTF8String): AnsiString;
begin
Result := WideStringToAnsiString(UTF8StringToWideString(s));
end;
function AnsiStringToUTF8String(Const s: AnsiString): UTF8String;
begin
Result := WideStringToUTF8String(AnsiStringToWideString(s));
end;
2015年08月14日 12点08分 7
大哥, MultiByteToWideChar这个函数需要引用什么单元?
2015年08月15日 01点08分
回复
����home
:[吐舌]Windows,我去试试
2015年08月15日 01点08分
level 5
随云home 楼主
我发现我的文件名乱码是通过两次转换成的,假设文件名问你‘hello你好’,用下面的函数转换
转换成这样,再用得到的字符串转换成字节显示就是和文件名乱码一样的,
其中log是memo显示; 然后我再把乱码还原,怎么还原不到中间的‘hello浣犲ソ.txt’;
现在问题只需要把这个’helloä½ å¥½.txt‘还原成这个‘hello浣犲ソ.txt’就好办了,有没有大神帮我看看
2015年08月15日 07点08分 8
‘hello浣犲ソ.txt’转换成’helloä½ å¥½.txt‘ 是通过下面代码转的,我还原过来就不行了 ///string转为Tbytes (转换成和文件名一样的乱码) Byte := BytesOf(S1); Edit2.Text := BytesToStr(Byte, 'str');
2015年08月15日 07点08分
回复
����home
:BytesToStr 在新版本中找不到了。 设 str := 你收到的乱码 ABytes :=TEncoding.ANSI.GetBytes(str); ANewStr := TEncodign.UTF8.GetStr(ABytes);
2015年08月17日 02点08分
str := 'helloä½ å¥½.txt'; ABytes :=TEncoding.ANSI.GetBytes(str); ANewStr := TEncoding.UTF8.GetString(ABytes); 我这样写有什么问题吗,报错
2015年08月17日 09点08分
@wang_80920 我把str赋值为字母或数字不报错,但换成乱码和中文是转不过来的。
2015年08月17日 09点08分
level 14
直接widestringtoansistring看看
2015年08月15日 09点08分 9
试了,转不回来
2015年08月17日 08点08分
level 14
服务器那边可能使用的事是ansistring
2015年08月15日 09点08分 10
level 10
建议在接收的之后将文件名用16进制写出来,就可以分析收到的是什么编码了,然后针对转码。
2015年08月15日 13点08分 11
已经用十六进制打印出来了,但是怎么分析是什么编码呢? 和中文的十六进制区别很大。
2015年08月17日 08点08分
回复 随云home :然后你要将原文件名用各种编码来对应16进制编码,看看是哪一种,总会找到的
2015年08月17日 14点08分
level 5
随云home 楼主
{****16进制单字符值*****}
function HexVal(c: char): Byte;
begin
if (c<'A') then result := ord(c) - ord('0')
else result := ord(c) - ord('A') + 10;
end;
{****16进制双字符值*****}
function Hex2Val(s: string): Byte;
begin
result := HexVal(s.Chars[0])*16 + HexVal(s.Chars[1]);
end;
{**********字符串转换成字节*******}
function StrToBytes(S, AFormat: string): TBytes;
var
i:Integer;
ss:TStrings;
begin
if(AFormat='Str') then begin
SetLength(result,s.Length);
for i:=0 to s.Length-1 do result[i]:=ord(s.Chars[i]);
end else begin
ss:=TStringList.Create;
ss.CommaText:=s.Trim.ToUpper.Replace(' ',',');
SetLength(result,ss.Count);
if(AFormat='HexStr') then for i:=0 to ss.Count-1 do result[i]:=Hex2Val(ss[i]);
if(AFormat='DecStr') then for i:=0 to ss.Count-1 do result[i]:=ss[i].ToInteger;
ss.Free;
end
end;
{**********字节转换成字符串*******}
function BytesToStr(b: TBytes; AFormat: string): string;
var
I: Byte;
begin
result := '';
if (AFormat = 'str') then for i in b do result := result + chr(I) else
if (AFormat = 'HexStr') then for I in b do result := result + I.ToHexString(2) + '' else
if (AFormat = 'DecStr') then for i in b do result := result + I.ToString() + '';
result := result.Trim;
end;
2015年08月18日 01点08分 12
level 5
随云home 楼主
我把原码放在这里,各位大神有空的话可以帮我看看[玫瑰]
[无效] http://pan.baidu.com/s/1c0jmZSk
2015年08月18日 01点08分 13
level 10
楼主白痴。
看了你的源码,就是你自己活该。
发送者必须传送
TNetEncoding.URL.Encode(文件名);
服务器收到后
文件名 ;= TNetEncoding.URL.Decode(FTP文件名);
不听就算了。
2015年08月18日 02点08分 14
大哥,客户端是摄像机,这个客户端是用来测试的,难道我要让摄像机改?
2015年08月18日 11点08分
回复
����home
:sorry 忘了你客户端不是你写的了。
2015年08月19日 01点08分
level 10
浪费时间。
2015年08月18日 02点08分 15
吧务
level 14
function Do_Decode(const S_Unicode: UnicodeString): UTF8String;
var
aBytes: TBytes;
i, aLength: Integer;
begin
aLength := Length(S_Unicode);
SetLength(aBytes, aLength);
for i := 1 to aLength do
aBytes[i - 1] := Word(S_Unicode[i]);
Result := TEncoding.UTF8.GetString(aBytes);
end;
function Do_Encode(const S_UTF8: UTF8String): UnicodeString;
var
aBytes: TBytes;
i, aLength: Integer;
begin
aBytes := TEncoding.UTF8.GetBytes(S_UTF8);
aLength := Length(aBytes);
SetLength(Result, aLength);
for i := 1 to aLength do
Result[i] := Char(Word(aBytes[i - 1]));
end;
2015年08月18日 02点08分 16
没注意看你的代码,现在看了,发现和楼下的,还有我的,一个意思。和楼下的一样,不跨平台。
2015年08月19日 03点08分
@wang_80920 嗯,用stringbuilder就可以跨平台了,反正就是个示例,写简单点容易理解。
2015年08月19日 03点08分
level 10
测试过你的代码,经确认写出来的16进制值是utf8编码。那么问题就很清楚了,你用的是xe6,string是宽字符的,你接收到的utf8字符串也被宽字符处理了,所以需要还原成ansistring来处理就解决了,验证代码如下:
2015年08月19日 00点08分 17
你说的这个是能把‘hello浣犲ソ.txt’转换成‘hello你好’,但是我接收到的文件是‘helloä½ å¥½.txt’,还是谢谢你啦
2015年08月19日 01点08分
回复
����home
:楼主没认真看代码?我只是没有把原始的afilename打印出来而已,你可以在前面加一句log(afilename)就明白了。
2015年08月19日 04点08分
回复
��ʥ������
:大哥,不好意思啊,我现在明白了,你的方法是能还原,但是我的AFilename过程传的参数,是string类型,sa定义的时候就是anstring类型,类型不匹配啊,我应该怎么做?(ps:不要耻笑我[太开心]
2015年08月20日 09点08分
回复
����home
:你照着打代码也有问题吗?这是循环每个字符实现的,循环中有强转的
2015年08月20日 11点08分
level 10
楼上的代码很好。就是有点不跨平台。
str := 'hello你好.txt';
aBytes := TEncoding.UTF8.GetBytes(str);
str := '';
for I := 0 to Length(ABytes) - 1 do
begin
str := str + Chr(ABytes[I] );
end;
//以上是生成错误编码的字符串。
SetLength(aBytes, Length(str));
for I := 0 to Length(ABytes) - 1 do
begin
ABytes[I] := Byte(str[Low(str) + I]);
end;
str := TEncoding.UTF8.GetString(ABytes);
2015年08月19日 01点08分 18
多谢指正 [呵呵]
2015年08月19日 03点08分
回复
��ʥ������
:没有你的创造性思维,我也不会写。
2015年08月19日 03点08分
@wang_80920 大哥,你的我测试了,可以的[哈哈]
2015年08月20日 09点08分
level 5
随云home 楼主
谢谢楼上两位大哥[花心]
2015年08月20日 09点08分 19
level 5
随云home 楼主
然后我把楼上大哥的代码写成函数,直接将乱码转换成中文了,真是太感谢 太感谢[哈哈]
2015年08月20日 12点08分 20
1