2012-09-10 8 views
6

D2007 से XE2 में कनवर्ट कर रहा है, मैंTENcoding प्रकार के फ़ंक्शन पैरामीटर के लिए डिफ़ॉल्ट मान कैसे सेट करें?

को यह समारोह

function Add_Line(FileStream : TFileStream; ALine : string) : boolean; 

परिवर्तित

function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding = nil) : boolean; 
var 
    AStr: ANSISTring; 
begin 
    Result := True; 
    if Enc = nil then Enc := TEncoding.ANSI; 
    try 
//Old FileStream.WriteBuffer(Pointer(ALine)^, Length(ALine)); 
    if Enc = TEncoding.UTF8 then 
     AStr := UTF8Encode(ALine) 
    else 
     AStr := ANSIString(ALine); 
    FileStream.WriteBuffer(AStr[1], Length(ALine)); 
    end; 
    except 
    Result := False; 
    end; 
end; 

दलील:

  • बदलें के रूप में संभव

  • थोड़ा के रूप में Add_Line का उपयोग कर कोड को स्वीकार करें यूनिक में स्वचालित परिवर्तन ओडीई, केवल आखिरी पल में 8-बिट टेक्स्ट फाइलें लिखें (इसका उपयोग एक्सएमएल और सीएसवी में किया जाता है)। भविष्य में हम अभी भी यूटीएफ -16 फाइलों पर जा सकते हैं यदि हम चाहते हैं।

मैं की तरह कुछ परिभाषित करने के लिए पसंद आया होगा:

function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding = TEncoding.ANSI) : boolean; 

लेकिन संकलक शिकायत ;-)

कि संभव ऐसा कुछ है?

+2

निरंतर मानों के लिए डिफ़ॉल्ट पैराम का प्रतिबंध एक कारण है कि मैं हमेशा ओवरलोड का उपयोग करने का पक्ष लेता हूं। –

+0

अधिभार कभी मेरे दिमाग को पार नहीं किया ;-) –

उत्तर

12

डिफ़ॉल्ट तर्क एक संकलन समय निरंतर होना चाहिए, लेकिन आप और अधिक उन्नत कुछ भी जरूरत है, आप भार के बना सकते हैं:

function Add_Line(FileStream : TFileStream; ALine : string) : boolean; overload; 
function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding) : boolean; overload; 


function Add_Line(FileStream : TFileStream; ALine : string) : boolean; 
begin 
    Result := Add_Line(FileStream, ALine, TEncoding.ANSI); 
end; 

तुम भी बिल्कुल वैसा ही उत्पन्न कोड प्राप्त करने के inline कीवर्ड जोड़ सकते हैं कि डिफ़ॉल्ट तर्क के परिणामस्वरूप, यह मान्य था।

नोट: आपको TEncoding.ANSI और TEncoding.UTF8 के अलावा कुछ भी समर्थन नहीं लगता है। उस स्थिति में, TEncoding पैरामीटर ओवरकिल लगता है, आप इसके बजाय UTF8: Boolean पैरामीटर का उपयोग कर सकते हैं (या अपने कोड को मनमाने ढंग से एन्कोडिंग के CodePage के साथ काम करने के लिए पुन: कार्य करें)।

नोट 2: FileStream.WriteBuffer(AStr[1], Length(ALine));, क्योंकि Length(ALine) और Length(AStr) एक ही होने की जरूरत नहीं गलत है आप Length(AStr) बजाय का उपयोग करना चाहिए। इसके अलावा, AStr[1] का परिणाम अपवाद हो सकता है जब AStr एक खाली स्ट्रिंग है, तो आप केवल WriteBuffer पर कॉल करने के लिए एक विशेष मामला जोड़ सकते हैं जब AStr खाली नहीं है।

+0

भविष्य के उपयोग के लिए मैं इसे एक टेनकोडिंग पैरामीटर छोड़ दूंगा, और लंबाई() टाइपो को इंगित करने के लिए धन्यवाद! भयानक डेटा का कारण बन सकता है ;-) –

5

अन्य ने टिप्पणी की है कि आप TEncoding पैरामीटर के लिए डिफ़ॉल्ट मान निर्दिष्ट कैसे कर सकते हैं। मैं यह इंगित करना चाहता हूं कि TEncoding का उपयोग सामान्य रूप से पूरी तरह से गलत है।

TEncoding.UTF8 एक ही तरीका है कि आप एक UTF-8 एन्कोडिंग वस्तु प्राप्त कर सकते हैं (TEncoding.GetEncoding(65001) एक और तरीका है) नहीं है, इसलिए TEncoding.UTF8 के लिए जाँच विशेष रूप से करने के लिए गलत बात है। इससे भी बदतर, आप किसी भी गैर-यूटीएफ 8 एन्कोडिंग को पूरी तरह से अनदेखा कर रहे हैं और केवल सादा AnsiString पर एन्कोडिंग एन्कोडिंग कर रहे हैं, जो TEncoding का उपयोग करने के पूरे उद्देश्य को हरा देता है। उदाहरण के लिए, उपयोगकर्ता एक आईएसओ -885 9-एक्स एन्कोडिंग ऑब्जेक्ट में पास कर सकता है, और आपका आउटपुट उपयोगकर्ता द्वारा अनुरोध किए गए आईएसओ एन्कोडेड नहीं होगा।साथ ही आप, बजाय एक UseUTF8: Boolean = False पैरामीटर में अपने पैरामीटर बदल सकते हैं क्योंकि यह है कि कैसे आप को प्रभावी ढंग से उपयोग कर रहे हैं:

function Add_Line(FileStream : TFileStream; ALine : string; UseUTF8: Boolean = False) : boolean; 
var 
    AStr: AnsiString; 
begin 
    Result := True; 
    try 
    if UseUTF8 then 
     AStr := UTF8Encode(ALine) 
    else 
     AStr := AnsiString(ALine); 
    if AStr <> '' then 
     FileStream.WriteBuffer(AStr[1], Length(AStr)); 
    except 
    Result := False; 
    end; 
end; 

सही उपयोग करने के लिए TEncoding यह वास्तविक एन्कोडिंग करते हैं करने के लिए है जिस तरह से, ऐसा नहीं करते हैं अपने आप को एन्कोडिंग:

function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding = nil) : boolean; 
var 
    AStr: TBytes; 
begin 
    if ALine = '' then 
    begin 
    Result := True; 
    Exit; 
    end; 
    Result := False; 
    try 
    if Enc = nil then Enc := TEncoding.Ansi; 
    AStr := Enc.GetBytes(ALine); 
    // GetBytes() returns 0 bytes if it fails to encode, it does not raise an exception! 
    if Length(AStr) = 0 then Exit; 
    FileStream.WriteBuffer(AStr[0], Length(AStr)) 
    except 
    Exit; 
    end; 
    Result := True; 
end; 
संबंधित मुद्दे