2016-12-19 3 views
2

У меня есть этот код: (я запускаю Delphi 7 на Win XP sp 3).TFileStream ведет себя очень странно

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

CONST 
    EOL = #13#10; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 

    procedure Button1Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    Procedure StringToStream(Ofile : TFileStream; Const StrValue : String); 

    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1 : TForm1; 
    Curdir : String; 
    Ofile : TFileStream; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    Ofile := TFileStream.Create(curdir + '\TESTfil.HTML', fmCreate,fmsharedenynone); 
    try 
     StringToStream(Ofile, '<HTML><BODY> </BODY></HTML>' + EOL); 
//  StringToStream(Ofile, '</BODY></HTML>' + EOL); 
    finally 
     Ofile.Free; 
    end; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Curdir := ExtractFileDir(Application.ExeName); 
end; 

Procedure Tform1.StringToStream(Ofile : TFileStream; Const StrValue : String); 

BEGIN 
    IF length(StrValue) > 0 then 
     Ofile.Write(StrValue,length(StrValue)); 
    Ofile.Write('testpunkt',9); 

END; 

И выход этого устройства:

"28 non printable characters" + "\testpunkt" 

Я попытался сделать строку «ФИКС». -> та же ошибка

Я пробовал с PChar в - есть много ошибок ... (в основном синтаксические ошибки)

Я изменил INDY7 к INDY9, чтобы получить idGlobal.WriteStringtoStream() - но это конкретный INDY-9 не поддерживает WriteStringToStream.

Что я делаю неправильно?

+0

На несвязанной ноте вы должны серьезно объявлять 'Curdir' и' Ofile' в классе формы, а не в модуле, а 'StringToStream' не должны быть объявлены над' private', а скорее под ' частный или публичный, в зависимости от требуемого объема. Пространство над 'private' обычно контролируется IDE. –

+0

@ Джерри Додж: Вы совершенно правы. Это устройство должно было быть очень преждевременным примером. И поскольку я не сделал это, я сделал несколько ярлыков, чтобы сократить код. Я мой настоящий код, я сделаю, как вы предлагаете. Спасибо за советы. –

ответ

5

Вы написали адрес строки, а не ее содержимое. Для того, чтобы написать строку в использовании потока этого код:

procedure TForm1.StringToStream(Ofile: TFileStream; const StrValue: string); 
begin 
    Ofile.WriteBuffer(Pointer(StrValue)^, Length(StrValue)); 
end; 

Здесь я разыменовываюсь указатель и так написано содержимое строки.

Примечания:

  • Этот код не нужно, чтобы проверить строку порожняком.
  • Поскольку вы используете Delphi 7, а строки ANSI, целесообразно пройти Length(StrValue). Если вы когда-нибудь перейдете в Юникод, вам придется изменить код для кодирования адреса.
  • Я использую WriteBuffer, а не Write, потому что первый будет создавать исключение в случае ошибки, в отличие от Write.
  • В вашем коде предполагается, что безопасно писать в тот же каталог, что и исполняемый файл. Это предположение может разрушиться, если вы когда-либо развертываете свою программу.
  • Ваше использование глобальных переменных просто настраивает вас на падение. См. Использование локальных переменных, где это возможно, переменные, переданные как параметры, члены данных классов. Shun globals.
  • Написание XML чревато осложнениями. Попытка сделать это с использованием операций с строкой строки, вероятно, приведет к множеству проблем с кодированием в какой-то момент в будущем. Разумным шагом было бы использовать библиотеку XML сейчас, чтобы вам не пришлось повторно писать код в будущем.
+0

Хефферман: Спасибо за все советы. Как я писал в своей записке (см. Примечание к Джерри Доджу), это был очень короткий пример. Спасибо за все ваши советы. –