1 ضمیمه
ذخیره متن Memo به صورت یونیکد
با سلام و عرض ادب
یک فایل یونیکد(هر کارکتر 2 بایت) رو خونده ام و کارکترهایی برای انتهای سطر اضافه کرده ام و جهت نوشتن عدد رو تغییر دادم و در Memo دلفی یونیکد(XE8) نمایش داده ام(کارکترهای عجیب هم داره که بعضی رو خودم طراحی کردم!)
میخوام متن Memo رو با حذف انتهای سطر و برگردادن عدد به حالت اول ، در فایل بنویسم. نتیجه نهایی نصف حجم رو داره!
ظاهرا Utf8 ذخیره میشه(اینجا گفته شده utf8 یونیکد هست!) ولی حجم نصف هست و متن فایل پر از کارکتر خط نیره و حروف انگلیسی میشه.
ضمیمه 156701
فکر کردم بهتره روش ذخیره ام رو هم توضیح بدم. هر دو روش زیر شکست خوردند (اما ذخیره بدون تغییر متن Memo داخل تصویر بالا، حجم رو نصف نمی کنهMemo1.Lines.SaveToFile(FileName)!):
روش اول ایجاد یک Memo مخفی روی فرم و اجرای کد زیر(S:متن تغییر یافته!):
Memo2.Lines.Text:=S;
Memo2.Lines.SaveToFile(FileName);
روش دوم:
SaveStr(FileName,S);
procedure SaveStr(FileName:String;S:String);
Var
F:File;
begin
AssignFile(F,FileName);
ReWrite(F,1);
Seek(F,0);
BlockWrite(F,Pointer(S)^,Length(S));
CloseFile(F);
end;
نقل قول: ذخیره متن Memo به صورت یونیکد
کشفیاتی کردم که نمی دونم چطور ممکنه.مثلا اینکه اگر قلم و متن Memo1 رو به Memo2 بدم و متن Memo2 رو ذخیره کنم باز حجم نصف میشه!
Memo2.Font.Assign(Memo1.Font);
Memo2.Text:=S;
Memo2.Lines.SaveToFile(FileName);
یک راه با سرعت پایین(برای حجم داده بالا ممکنه کند بودنش محسوس باشه!) پیدا کردم که حجم رو نصف نمی کنه :
اول متن Memo1 رو در متغیر PreS:String ذخیره می کنم و بعد از تغییر متن و حذف و تبدیل کارکتر کد زیر رو اجرا می کنم:
Memo1.Lines.BeginUpdate;
Memo1.Text:=S;
Memo1.Lines.SaveToFile(FileName);
Memo1.Text:=PreS;
Memo1.Lines.EndUpdate;
ظاهرا نهایی متن مشابه اولیه هست اما نمی دونم واقعا یکی هست یا نه.
چون وقتی متن اولیه و نهایی رو با Memo1.Lines.LoadFromFile در دو متغییر می ریزم، دو متغیر دقیقا یک رشته دارند:
Memo1.Lines.LoadFromFile('F:\Delphi\Other Prgs\TestUnicode\BOK84441\G01\A.txt');
A:=Memo1.Lines.Text;
Memo1.Lines.LoadFromFile('F:\Delphi\Other Prgs\TestUnicode\BOK84441\G01\B.txt');
B:=Memo1.Lines.Text;
if A=B then
Msg('Yes!');
اما اگر با پروسیجر زیر، متن فایل اولیه و فایل نهایی رو در متغیر بریزم، با اینکه حجم یکی هست، دقیقا از کارکتر وسط+1 به بعد، کارکترهاشون متفاوت هستند:
procedure LoadStr(FileName:String;var S:String);
Var
Stream : TFileStream;
begin
Stream := TFileStream.Create(FileName,fmOpenRead);
try
Stream.Position := 0;
SetLength(S,Stream.Size);
Stream.Read(S[1], Stream.Size);
finally
Stream.Free;
end;
end;
متوجه شدم اگر A,B,S رو از نوع WideString و نه String تعریف کنم، باز هم کارکترهای دو فایل اولیه و نهایی دقیقا یکی میشه. ولی UnicodeString همون مشکل تفاوت کارکتر بعد از نیمه رو داره!
procedure LoadStr(FileName:String;var S:WideString);
کاش یکی پیدا میشد کمی توضیح بده. استفاده از Memo با تغییر کارکتر و برگردادند به حالت اول در پس زمینه، روش اصولی نیست و کند هست!
اصلا یونیکد چیه؟(فکر می کردم باید دو بایتی باشه) UnicodeString , WideString چرا فرق دارند؟(در راهنما گفته شده UnicodeString ميتونه AnsiString باشه!)
آیا راهی برای تبدیل String به WideString هست و بالعکس؟ یا همه توابع و پروسیجرهایی که برای کار روی متن memo نوشتم باید پارامترهایی با نوع WideString بگیرند!
مثلا من چنین پروسیجری نوشتم ولی فکر کنم برای خنده خوب باشه:لبخند:
Procedure StrToWideStr(A:String;Var B:WideString);Begin
MultiByteToWideChar(DefaultSystemCodePage,0,PAnsiC har(A),Length(A),PWideChar(B),Length(A)*2);
End;
چرا حجم(Length!) Memo1.TextوAوB میشه 9713 اما حجم فایل میشه 19428 بایت!
دلفی و ویندوز، چطور میفهمند محتوای فایل چه نوع رشته ای هست؟