2012-03-08 23 views
8

Not Defteri'nde herhangi bir Dosya Açabilirsiniz ve içerdeki ham verileri gösterecektir.Notta herhangi bir Dosya Aç?

Bunu bir TMemo'da yapmak istiyorum, ancak bunu nasıl yapacağınızı öğrenmek için uğraştım.

ben onu işleve modifiye bu code here.

bulmayı başardılar ve biraz benim amaçlar için değiştirdi:

function OpenBinaryFile(var Data; Count: Cardinal): string; 
var 
    Line: string[80]; 
    i: Cardinal; 
    P: PAnsiChar; 
    nStr: string[4]; 
    SL: TStringList; 
const 
    posStart = 1; 
    binStart = 7; 
    ascStart = 57; 
begin 
    P := @Data; 
    Line := ''; 

    SL := TStringList.Create; 
    try 
    for i := 0 to Count - 1 do 
    begin 
     if (i mod 16) = 0 then 
     begin 
     if Length(Line) > 0 then 
      SL.Add(Trim(Line)); 

     FillChar(Line, SizeOf(Line), ' '); 
     Line[0] := Chr(72); 
     end; 

    if P[i] >= ' ' then 
     Line[i mod 16 + ascStart] := P[i] 
    else 
     Line[i mod 16 + ascStart] := '.'; 
    end; 

    SL.Add(Trim(Line)); 

    Result := SL.Text; 
finally 
    SL.Free; 
    end; 
end; 

O çalışır, ancak satır başına karakter sabit miktarda sadece görüntüler böyle: Ben aynı wa tüm notu doldurur böylece değiştirmem gerekiyor ne

enter image description here

y Not Defteri?

cevap

9

Bu, 16 karakterde satırları kesen if (i mod 16) = 0 sınamasıdır.

ben Not Defteri bu koduyla aynı yapar inanıyoruz:

var 
    i: Integer; 
    s: AnsiString; 
    Stream: TFileStream; 
begin 
    Stream := TFileStream.Create(FileName, fmOpenRead); 
    try 
    SetLength(s, Stream.Size); 
    if Stream.Size>0 then 
     Stream.ReadBuffer(s[1], Stream.Size); 
    finally 
    Stream.Free; 
    end; 
    for i := 1 to Length(s) do 
    if s[i]=#0 then 
     s[i] := ' '; 
    Memo1.Text := s; 
end; 

sonra kolayca böyle yukarıdaki kodu değiştirerek bunu yapabilirsiniz '.' olmayan yazdırılabilir karakterleri değiştirmek isterseniz:

D2009'da TEncoding
+0

, David teşekkür harika That. Çeşitli çözümler ararken bazı yorumları okuyordum ve bazıları BlockRead'in kullanımından bahsediyordu. Açtığım dosyalar nispeten küçük, ama yine de bunu dikkate almalı mıyım, yoksa cevabınız buna ihtiyaç duymuyor mu çünkü Stream’den okunıyormuş gibi görünüyor? –

+0

Her zaman eski stil pascal io –

+0

yerine bir akım kullanırdım. Eh, eski stil Pascal kullanmadım, hala modern Delphi'yi öğreniyorum :) Okumaya çalıştığım makaleler/parçacıklar muhtemelen bunu açıklayabilecek eskimişti. Çözümünüz gerçekten düzenli ve verimli, kolay görünmesini sağlıyorsunuz. Çok teşekkür ederim :) –

3

TStrings bir yazılım oldu. Varsayılan olarak, TStrings.LoadFrom...() aksi belirtilmedikçe TEncoding.Default kullanır.

type 
    TRawEncoding = class(TEncoding) 
    protected 
    function GetByteCount(Chars: PChar; CharCount: Integer): Integer; override; 
    function GetBytes(Chars: PChar; CharCount: Integer; Bytes: PByte; ByteCount: Integer): Integer; override; 
    function GetCharCount(Bytes: PByte; ByteCount: Integer): Integer; override; 
    function GetChars(Bytes: PByte; ByteCount: Integer; Chars: PChar; CharCount: Integer): Integer; override; 
    public 
    constructor Create; 
    function GetMaxByteCount(CharCount: Integer): Integer; override; 
    function GetMaxCharCount(ByteCount: Integer): Integer; override; 
    function GetPreamble: TBytes; override; 
    end; 

: G/okur ham 8-bitlik veri yazar özel TEncoding türetilmiş bir sınıf, örneğin uygulanması tavsiye ediyor.

constructor TRawEncoding.Create; 
begin 
    FIsSingleByte := True; 
    FMaxCharSize := 1; 
end; 

function TRawEncoding.GetByteCount(Chars: PChar; CharCount: Integer): Integer; 
begin 
    Result := CharCount; 
end; 

function TRawEncoding.GetBytes(Chars: PChar; CharCount: Integer; Bytes: PByte; ByteCount: Integer): Integer; 
var 
    i : Integer; 
begin 
    Result := Math.Min(CharCount, ByteCount); 
    for i := 1 to Result do begin 
    // replace illegal characters > $FF 
    if Word(Chars^) > $00FF then begin 
     Bytes^ := Byte(Ord('?')); 
    end else begin 
     Bytes^ := Byte(Chars^); 
    end; 
    //advance to next char 
    Inc(Chars); 
    Inc(Bytes); 
    end; 
end; 

function TRawEncoding.GetCharCount(Bytes: PByte; ByteCount: Integer): Integer; 
begin 
    Result := ByteCount; 
end; 

function TRawEncoding.GetChars(Bytes: PByte; ByteCount: Integer; Chars: PChar; CharCount: Integer): Integer; 
var 
    i : Integer; 
begin 
    Result := Math.Min(CharCount, ByteCount); 
    for i := 1 to Result do begin 
    Word(Chars^) := Bytes^; 
    //advance to next char 
    Inc(Chars); 
    Inc(Bytes); 
    end; 
end; 

function TRawEncoding.GetMaxByteCount(CharCount: Integer): Integer; 
begin 
    Result := CharCount; 
end; 

function TRawEncoding.GetMaxCharCount(ByteCount: Integer): Integer; 
begin 
    Result := ByteCount; 
end; 

function TRawEncoding.GetPreamble: TBytes; 
begin 
    SetLength(Result, 0); 
end; 

Sonra bu gibi kullanabilirsiniz:

var 
    Enc: TEncoding; 
begin 
    Enc := TRawEncoding.Create; 
    try 
    Memo1.Lines.LoadFromFile('filename', Enc); 
    finally 
    Enc.Free; 
    end; 
end; 
+0

Mükemmel bilgi ve kod örneği çok teşekkür ederim Remy. Programlamada ve Delphi'de bir şeyler yapmak için her zaman birden fazla yolun olduğu beni şaşırtıyor - ama daha sık tek bir şekilde anlayamıyorum! Çözümünüz David'inkinden tamamen farklıdır, ancak her ikisi de gerçekten faydalı olan farklı yaklaşımları gösterir :) –

İlgili konular