2012-03-08 11 views
8

メモ帳で任意のファイルを開くことができ、その中に生データが表示されます。メモ内の任意のファイルを開きますか?

私はTMemoでこれをやりたいのですが、これを行う方法を見つけるのに苦労しています。

私は機能にそれを修正し、私の目的のために、わずかにそれを変更し、このcode here.

を見つけることができた:

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; 

それは動作しますが、それが唯一の行あたりの文字数の固定額で表示します、このような:私はそれが同じワシントン州のすべてのメモを満たすように変更する必要が何

enter image description here

yメモ帳は?

答えて

9

これは、if (i mod 16) = 0という16文字の行を切り詰めるテストです。

私はメモ帳は、このコードと同じことをすることを信じる:

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; 

あなたは'.'でない文字を置き換えたい場合、あなたは簡単にこのように上記のコードを変更することによって、そうすることができます。

if s[i]<#32 then 
    s[i] := '.'; 
+0

素晴らしいことだそれあなたのデビッドに感謝。私はさまざまな解決策を探している間にいくつかのコメントを読んでいて、BlockReadの使用について言及しています。私が開いているファイルは比較的小さいですが、とにかくそれを検討する必要がありますか、答えがストリームを介して読み込まれているように見えるため、答えは必要ありませんか? –

+0

私はいつも古いスタイルのパスカルioではなくストリームを使用します –

+0

まあ、私は古いスタイルのパスカルを使ったことがなく、現代のDelphiをまだ学んでいません:)私が読んでいた記事/スニペットは、あなたのソリューションは本当にきれいで効率的です。あなたは見た目が簡単です。ありがとうございます:) –

3

TStringsがD2009でTEncodingになったことを認識しました。デフォルトでは、特に指定しない限りTStrings.LoadFrom...()は​​を使用します。

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; 

:私は/生8ビットのデータを読み書きするカスタムTEncoding派生クラス、例えばを実装することをお勧め。

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; 

その後、あなたはこのようにそれを使用することができます:

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

優れた情報とコードの例は非常にレミーにありがとうございます。私は、プログラミングとDelphiで何かをする方法が常に複数あることを驚かせていますが、それよりも多くの場合、1つの方法しか理解できません。あなたのソリューションはDavidとはまったく異なりますが、どちらも本当に便利なさまざまなアプローチを示しています:) –

関連する問題