delphi写入文件oem编码

delphi写入文件oem编码,delphi,encoding,Delphi,Encoding,如何写入Delphi文件,oem编码 如何设置编码?因为字符串编码是由 setCodePage(RawBytes;Word;boolean); 轻松地。这取决于要使用的文件I/O方法。其中一个例子: procedure TForm11.FormCreate(Sender: TObject); var S: string; begin DefaultSystemCodePage := GetOEMCP(); S := 'Если используешь мой код, то ты

如何写入Delphi文件,oem编码

如何设置编码?因为字符串编码是由

setCodePage(RawBytes;Word;boolean);

轻松地。这取决于要使用的文件I/O方法。其中一个例子:

procedure TForm11.FormCreate(Sender: TObject);
var
  S: string;
begin
  DefaultSystemCodePage := GetOEMCP(); 
  S := 'Если используешь мой код, то ты должен мне почку';
  AssignFile(Output, 'license.txt');
  Rewrite(Output);
  Write(Output, S); // converts to single byte here
  CloseFile(Output);
  Application.Terminate;
end;

请不要抱怨Pascal I/O:-p

您需要Windows API函数


编辑

受@Free Consulting的启发,上述API是您将在较旧的非Unicode Delphi中使用的API

正如@Free Consulting正确指出的那样,新版本的Delphi提供了广泛的代码页翻译服务。作为旧式Pascal I/O的更现代的变体,您可以使用使用指定编码保存的TStringList

Encoding := TEncoding.GetEncoding(GetOEMCP);
Try
  StringList.SaveToFile('test.txt', Encoding);
Finally
  Encoding.Free;
End;

我写了一个函数来实现这一点。它不漂亮,但很管用

function SetFileContent(aFileName: string; aFileContent: string; out aErrorMsg: string; aEncoding: TEncoding = nil; aRecreateFile: Boolean = True): Boolean;
var
  vStream: TFileStream;
  vCurEncoding: TEncoding;
  vPreamble, vContent: TBytes;
  vOffSet: Integer;

  procedure _SetFileContent(aNewFile: Boolean);
  begin
    if aNewFile then begin
      vStream := TFileStream.Create(aFileName, fmCreate);
      try
        vPreamble := aEncoding.GetPreamble;
        If Length(vPreamble) > 0 then begin
          vStream.WriteBuffer(Pointer(vPreamble)^, Length(vPreamble));
        end;
        vStream.WriteBuffer(Pointer(vContent)^, Length(vContent));
      finally
        vStream.Free;
      End;
    end
    else begin
      vStream := TFileStream.Create(aFileName, fmOpenWrite);
      try
        vStream.Position := vStream.Size;
        vStream.WriteBuffer(Pointer(vContent)^, Length(vContent));
      finally
        vStream.Free;
      end;
    end;
  end;

begin
  Result := True;
  try
    vContent := BytesOf(aFileContent);
    vCurEncoding := nil;
    if aEncoding = nil then begin
      aEncoding := TEncoding.Default;
    end;
    vOffSet := TEncoding.GetBufferEncoding(vContent, vCurEncoding);
    if (vCurEncoding <> aEncoding) and aRecreateFile then begin
      vContent := TEncoding.Convert(vCurEncoding, aEncoding, vContent, vOffSet,     Length(vContent) - vOffSet);
    end;
    if FileExists(aFileName) then begin
      if aRecreateFile then begin
        _SetFileContent(True);
      end
      else begin
        _SetFileContent(False);
      end;
    end
    else begin
      _SetFileContent(True);
    end;
  except
    on E: Exception do begin
      Result := False;
      aErrorMsg := 'There was an error while trying to write the string ' + aFileContent + ' in the file ' + aFileName + '. Error: ' + E.Message;
    end;
  end;
end;
函数SetFileContent(aFileName:string;aFileContent:string;out-aerrormg:string;aencode:TEncoding=nil;aRecreateFile:Boolean=True):布尔;
变量
vStream:TFileStream;
vCURENCODE:十位编码;
vStream,vContent:t字节;
vOffSet:整数;
过程_SetFileContent(aNewFile:Boolean);
开始
如果没有文件,则开始
vStream:=TFileStream.Create(aFileName,fmCreate);
尝试
vStreamble:=AENCODE.GetPreamble;
如果长度(vStreamble)>0,则开始
WriteBuffer(指针(vStream)^,长度(vStream));
结束;
WriteBuffer(指针(vContent)^,长度(vContent));
最后
vStream.Free;
结束;
结束
否则开始
vStream:=TFileStream.Create(aFileName,fmOpenWrite);
尝试
vStream.Position:=vStream.Size;
WriteBuffer(指针(vContent)^,长度(vContent));
最后
vStream.Free;
结束;
结束;
结束;
开始
结果:=真;
尝试
vContent:=字节数(aFileContent);
vCURENCODE:=零;
如果AENCODE=nil,则开始
aEncoding:=TEncoding.Default;
结束;
vOffSet:=TEncoding.GetBufferEncoding(vContent,vCurEncoding);
如果(vCURENCODE AENCODE)和aRecreateFile,则开始
vContent:=TEncoding.Convert(vcurencoded,aencode,vContent,vOffSet,Length(vContent)-vOffSet);
结束;
如果文件存在(文件名),则开始
如果是CreateFile,则开始
_SetFileContent(True);
结束
否则开始
_SetFileContent(False);
结束;
结束
否则开始
_SetFileContent(True);
结束;
除了
在E上:异常确实开始
结果:=假;
aErrorMsg:='尝试在文件'+aFileName+'中写入字符串'+aFileContent+'时出错。错误:'+E.消息;
结束;
结束;
结束;

TStringList.SaveToFile()
有一个
TEncoding
参数,您可以使用
TEncoding.GetEncoding()
为任何已安装的代码页获取编码对象,因此您可以为此指定
getoecmp()
的返回值。或者使用
TFileStream
FileWrite()
手动写入文件,然后在写入过程中使用
TEncoding.GetBytes()
String
值进行编码。

为什么不使用Unicode,特别是UTF-8编码?然后一切都很简单。这不取决于我,另一边仍然使用旧的编码。因为我尝试支持新的编码。一点也不支持,因为RTL现在本机支持翻译。您的代码将转换为windows上的默认代码页,而OP显然希望转换为一个特定的代码页(因此示例代码中的例程将代码页作为参数)。此外,12行代码的一个肾脏太贵了。@Cosmin Prund,不,你没有读过,这段代码使用隐式翻译来设置当前的OEM代码页。这就是为什么它值得每一个肾脏:-PIt还影响所有的解析转换,而不仅仅是文件I/O。