// 把Unicode编码的文件另存为Ansi编码的文件
// 未考虑文件名为Unicode的情况,因为没有这样的文件,不知如何判断。
function FileUnideToAnsi(UnicodeFileName,AnsiFileName : String) : Boolean;
var
aFileStream : TFileStream;
ReturnValue,BuffSize,AnsiLen : Int64;
Buffer : array of Byte;
aWideString : WideString;
PtmpStr : PChar;
errCode : Cardinal;
begin
Result := False;
if not FileExists(UnicodeFileName) then exit; aFileStream := TFileStream.Create(UnicodeFileName,fmOpenRead);
memo1.Lines.add('文件流大小:' + intTostr(aFileStream.Size)); afileStream.Position := 0;
BuffSize := 2;
setLength(Buffer,BuffSize);
if afileStream.Read(Buffer[0],BuffSize) <> BuffSize then exit;
memo1.Lines.add('读标志返回:' + intToHex(Buffer[0],2) + intToHex(Buffer[1],2));
if intToHex(Buffer[0],2) + intToHex(Buffer[1],2) <> 'FFFE' then exit; // 不是Unicode文本 afileStream.Position := 2; // 前面的标志不读
BuffSize := (afileStream.Size -2);
setLength(aWideString,BuffSize);
ReturnValue := afileStream.Read(PWideString(aWideString),BuffSize);
memo1.Lines.add('读流返回字节数:' + intToStr(ReturnValue));
memo1.Lines.add('aWideString大小:' + intTostr(length(aWideString))); // 在这里报错,为什么? AnsiLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), BuffSize, PtmpStr, 0, Nil, Nil); //这个调用方法,有问题吗?
memo1.Lines.add('转换后的字符串大小:' + intTostr(AnsiLen));
getMem(PtmpStr,AnsiLen + 1);
try
ReturnValue := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), BuffSize, PtmpStr, AnsiLen , Nil, Nil); errCode := getLastError;
if errCode = NOERROR then
memo1.Lines.add('转换成功')
else if errCode = ERROR_INSUFFICIENT_BUFFER then
memo1.Lines.add('错误:ERROR_INSUFFICIENT_BUFFER')
else if errCode = ERROR_INVALID_FLAGS then
memo1.Lines.add('错误:ERROR_INVALID_FLAGS')
else if errCode = ERROR_INVALID_PARAMETER then
memo1.Lines.add('错误:ERROR_INVALID_PARAMETER')
else
memo1.Lines.add('未知错误值:' + intToStr(errCode));
if ReturnValue = 0 then exit; //转换不成功 memo1.Lines.add('返回值:' + intTostr(ReturnValue));
memo1.Lines.Add(strpas(PtmpStr));
aFileStream.NewInstance; //用free不行,用这个也有问题,该怎么用?
If not FileExists(AnsiFileName) then
Fileclose(FileCreate(AnsiFileName));
aFileStream.Create(AnsiFileName,fmOpenWrite);
aFileStream.Write(PtmpStr,ReturnValue);
result := True;
finally
aFileStream.Free;
freeMem(PtmpStr,AnsiLen + 1);
end;
end;
// 未考虑文件名为Unicode的情况,因为没有这样的文件,不知如何判断。
function FileUnideToAnsi(UnicodeFileName,AnsiFileName : String) : Boolean;
var
aFileStream : TFileStream;
ReturnValue,BuffSize,AnsiLen : Int64;
Buffer : array of Byte;
aWideString : WideString;
PtmpStr : PChar;
errCode : Cardinal;
begin
Result := False;
if not FileExists(UnicodeFileName) then exit; aFileStream := TFileStream.Create(UnicodeFileName,fmOpenRead);
memo1.Lines.add('文件流大小:' + intTostr(aFileStream.Size)); afileStream.Position := 0;
BuffSize := 2;
setLength(Buffer,BuffSize);
if afileStream.Read(Buffer[0],BuffSize) <> BuffSize then exit;
memo1.Lines.add('读标志返回:' + intToHex(Buffer[0],2) + intToHex(Buffer[1],2));
if intToHex(Buffer[0],2) + intToHex(Buffer[1],2) <> 'FFFE' then exit; // 不是Unicode文本 afileStream.Position := 2; // 前面的标志不读
BuffSize := (afileStream.Size -2);
setLength(aWideString,BuffSize);
ReturnValue := afileStream.Read(PWideString(aWideString),BuffSize);
memo1.Lines.add('读流返回字节数:' + intToStr(ReturnValue));
memo1.Lines.add('aWideString大小:' + intTostr(length(aWideString))); // 在这里报错,为什么? AnsiLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), BuffSize, PtmpStr, 0, Nil, Nil); //这个调用方法,有问题吗?
memo1.Lines.add('转换后的字符串大小:' + intTostr(AnsiLen));
getMem(PtmpStr,AnsiLen + 1);
try
ReturnValue := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), BuffSize, PtmpStr, AnsiLen , Nil, Nil); errCode := getLastError;
if errCode = NOERROR then
memo1.Lines.add('转换成功')
else if errCode = ERROR_INSUFFICIENT_BUFFER then
memo1.Lines.add('错误:ERROR_INSUFFICIENT_BUFFER')
else if errCode = ERROR_INVALID_FLAGS then
memo1.Lines.add('错误:ERROR_INVALID_FLAGS')
else if errCode = ERROR_INVALID_PARAMETER then
memo1.Lines.add('错误:ERROR_INVALID_PARAMETER')
else
memo1.Lines.add('未知错误值:' + intToStr(errCode));
if ReturnValue = 0 then exit; //转换不成功 memo1.Lines.add('返回值:' + intTostr(ReturnValue));
memo1.Lines.Add(strpas(PtmpStr));
aFileStream.NewInstance; //用free不行,用这个也有问题,该怎么用?
If not FileExists(AnsiFileName) then
Fileclose(FileCreate(AnsiFileName));
aFileStream.Create(AnsiFileName,fmOpenWrite);
aFileStream.Write(PtmpStr,ReturnValue);
result := True;
finally
aFileStream.Free;
freeMem(PtmpStr,AnsiLen + 1);
end;
end;
解决方案 »
- delphi dbgridEh 的继承
- !!!和大家分享一个搞笑得提问贴!!!!
- 老问题: 如何使DBGridEh 各行显示不同的背景色?再是当前行显第三种背景颜色,字体显示蓝色?
- 感谢所有帮过我的人。
- 如何在DBGrid最后一条记录后插入一行空行!!高分求救世主100。
- delphi/kylix的UML工具--见第一篇
- 偶遇到了一个难题!就是怎么样开发一个群发手机短信的平台呢??大家集思广益一下解决我的困遇,急呀~~
- IE核心
- 同志们................DELPHI7耶
- 高手帮忙看看这个 exe程序的注册密码. 谢谢!
- 关于ima/img文件的操作问题
- 常用的方法,可是我不会,请教各位啊,谢谢。
function isUnicode(filename: string): boolean;
var
f: file of byte;
b1, b2: Byte;
begin
result := false;
try
AssignFile(F, filename);
Reset(f);
Read(f, b1);
Read(f, b2);
if (b1 = $FF) and (b2 = $FE) then
Result := true;
finally
CloseFile(f);
end;
end;function UnicodeFileToString(FileName, newfilename: string): boolean;
const
iUnicodeLen = 4;
var
p: Pointer;
ms: TMemoryStream;
i: integer;
begin
result := false;
if not isUnicode(FileName) then
exit;
ms := nil;
ms := TMemoryStream.Create;
try
ms.LoadFromFile(FileName);
i := integer(ms.memory);
p := nil;
p := Ptr(i - iUnicodeLen); // 前4个这字节不是需要的内容。
WideCharLenToString(p, ms.Size - iUnicodeLen);
ms.SaveToFile(newfilename);
result := true;
finally
ms.Free;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
// WideCharToMultiByte()
// WideCharLenToString();
if UnicodeFileToString(Edit1.Text, 'c:\a.txt') then
showmessage('ok');
end;
// 未考虑文件名为Unicode的情况,因为没有这样的文件,不知如何判断。
function FileUnideToAnsi(UnicodeFileName,AnsiFileName : String) : Boolean;
var
aFileStream : TFileStream;
ReturnValue,BuffSize,AnsiLen : Int64;
Buffer : array of Byte;
aWideString : WideString;
PtmpStr : PChar;
errCode : Cardinal;
begin
with form1 do
begin
Result := False;
if not FileExists(UnicodeFileName) then exit;
aFileStream := nil; //
// aFileStream := TFileStream.Create(UnicodeFileName,fmOpenRead);
aFileStream := TFileStream.Create(UnicodeFileName,fmOpenRead or fmsharedenywrite);
mmo1.Lines.add('文件流大小:' + intTostr(aFileStream.Size)); afileStream.Position := 0;
BuffSize := 2;
setLength(Buffer,BuffSize);
if afileStream.Read(Buffer[0],BuffSize) <> BuffSize then exit;
mmo1.Lines.add('读标志返回:' + intToHex(Buffer[0],2) + intToHex(Buffer[1],2));
if intToHex(Buffer[0],2) + intToHex(Buffer[1],2) <> 'FFFE' then exit; // 不是Unicode文本 afileStream.Position := 2; // 前面的标志不读
BuffSize := (afileStream.Size -2);
setLength(aWideString,BuffSize);
// ReturnValue := afileStream.Read(PWideString(aWideString),BuffSize);
ReturnValue := afileStream.Read(PWideString(aWideString)^, BuffSize); // 读到变量内存,所以要是变量的值。
mmo1.Lines.add('读流返回字节数:' + intToStr(ReturnValue));
mmo1.Lines.add('aWideString大小:' + intTostr(length(aWideString))); // 在这里报错,为什么?// AnsiLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), BuffSize, PtmpStr, 0, Nil, Nil); //这个调用方法,有问题吗?
PtmpStr := nil;
AnsiLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), -1, PtmpStr, 0, Nil, Nil); //这个调用方法,有问题吗?
ShowMessage(SysErrorMessage(GetLastError));
mmo1.Lines.add('转换后的字符串大小:' + intTostr(AnsiLen));
getMem(PtmpStr,AnsiLen + 1);
try
// ReturnValue := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), BuffSize, PtmpStr, AnsiLen, Nil, Nil);
ReturnValue := WideCharToMultiByte(CP_ACP, 0, PWideChar(aWideString), -1, PtmpStr, AnsiLen, Nil, Nil);
ShowMessage(SysErrorMessage(GetLastError));
// if ReturnValue = 0 then exit; //转换不成功 mmo1.Lines.add('返回值:' + intTostr(ReturnValue));
PtmpStr[ReturnValue] := #0;
mmo1.Lines.Add(strpas(PtmpStr));
// aFileStream.NewInstance; //用free不行,用这个也有问题,该怎么用?
aFileStream.Free;
// If not FileExists(AnsiFileName) then
// Fileclose(FileCreate(AnsiFileName));
// aFileStream.Create(AnsiFileName,fmOpenWrite);
aFileStream := TFileStream.Create(AnsiFileName,fmOpenWrite);
// aFileStream.Write(PtmpStr, ReturnValue);
aFileStream.Write(PtmpStr^, ReturnValue);
result := True;
finally
aFileStream.Free;
freeMem(PtmpStr,AnsiLen + 1);
end;
end; // with
end;
Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串.int MultiByteToWideChar( UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // address of string to map
int cchMultiByte, // number of characters in string
LPWSTR lpWideCharStr, // address of wide-character buffer
int cchWideChar // size of buffer
);uCodePage参数用于标识一个与多字节字符串相关的代码页号。dwFlags参数用于设定另一个控件,
它可以用重音符号之类的区分标记来影响字符。这些标志通常并不使用,而在dwFlags参数
中则传递0。pMultiByteStr参数用于设定要转换的字符串,cchMultiByte参数用于指明
该字符串的长度(按字节计算)。如果你为cchMultiByte参数传递-1,那么该函数用于
确定源字符串的长度。转换后产生的Unicode版本字符串将被写入内存中的缓存,其地址
由pWideCharStr参数指定。你必须在cchWideChar参数中设定该缓存的最大值(以字符为
计量单位)。如果你调用MultiByteToWideChar,给cchWideChar参数传递0,那么该参数
将不执行字符串的转换,而是返回为使转换取得成功所需要的缓存的值。通过下列步骤
将多字节字符串转换成Unicode等价字符串:1. 调用MultiByteToWideChar函数,为pWideCharStr参数传递NULL,为cchWideChar
参数传递0。
2. 分配足够的内存块,用于存放转换后的Unicode字符串。该内存块的大小值由前面的对MultByteToWideChar的调用返回。
3. 再次调用MultiByteToWideChar,这次将缓存的地址作为pWideCharStr参数来传递,并传递第一次调用MultiByteToWideChar时返回的缓存大小值,作为cchWidechar参数。
4. 使用转换后的字符串。
5. 释放Unicode字符串占用的内存块。