2012-03-08 17 views
8

नोटपैड में आप कोई भी फ़ाइल खोल सकते हैं और यह कच्चे डेटा को अंदर प्रदर्शित करेगा।मेमो में कोई भी फाइल खोलें?

मैं इसे टीएममो में करना चाहता हूं लेकिन यह पता लगाने के लिए संघर्ष किया है कि यह कैसे करें।

मैं इस 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

क्या मैं यह एक ही वा में सभी ज्ञापन भरता है तो बदलने की जरूरत है वाई नोटपैड होगा?

उत्तर

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

बहुत बढ़िया आप डेविड धन्यवाद। मैं विभिन्न समाधानों की तलाश करते समय कुछ टिप्पणियां पढ़ रहा था और कुछ ब्लॉकर के उपयोग का जिक्र करते हैं। जिन फ़ाइलों को मैं खोल रहा हूं वे अपेक्षाकृत छोटे हैं, लेकिन क्या मुझे इसे किसी भी तरह से विचार करने की आवश्यकता है, या क्या आपके उत्तर की आवश्यकता नहीं है क्योंकि ऐसा लगता है कि यह स्ट्रीम के माध्यम से पढ़ा जाता है? –

+0

मैं हमेशा पुराने स्टाइल पास्कल io –

+0

की बजाय स्ट्रीम का उपयोग करता हूं, ठीक है मैंने कभी भी पुराने स्टाइल पास्कल का उपयोग नहीं किया है, अभी भी आधुनिक डेल्फी सीख रहा है :) लेख/स्निपेट जो मैं पढ़ रहा था शायद पुराना था जो इसे समझा सकता है। आपका समाधान वास्तव में साफ और कुशल है, आप इसे आसान लगते हैं। बहुत बहुत धन्यवाद :) –

3

TStringsTEncoding -10 में डीए 200 9 में बने। डिफ़ॉल्ट रूप से, TStrings.LoadFrom...()TEncoding.Default का उपयोग करेगा जबतक कि आप इसे अन्यथा नहीं बताते।

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; 

: मैं एक कस्टम TEncoding व्युत्पन्न वर्ग पढ़ता है कि/कच्चे 8 बिट डेटा लिखते हैं, जैसे को लागू करने का सुझाव देते हैं।

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

उत्कृष्ट जानकारी और कोड उदाहरण आपको बहुत धन्यवाद। यह मुझे आश्चर्यचकित करता है कि प्रोग्रामिंग और डेल्फी में कुछ करने के लिए हमेशा एक से अधिक तरीके हैं - फिर भी अधिकतर नहीं कि मैं एक ही तरीके से नहीं समझ सकता! आपका समाधान डेविड के लिए बिल्कुल अलग है, लेकिन दोनों अलग-अलग दृष्टिकोण दिखाते हैं जो वास्तव में उपयोगी हैं :) –

संबंधित मुद्दे