একটি সি # কনসোল অ্যাপ্লিকেশনটিতে, কোনও পাঠ্য ফাইলে মিরর করে কনসোল আউটপুট দেওয়ার কোনও স্মার্ট উপায় আছে কি?
বর্তমানে আমি উভয় Console.WriteLine
এবং InstanceOfStreamWriter.WriteLine
লগ পদ্ধতিতে একই স্ট্রিংটি পার করছি ।
উত্তর:
এটি আরও একরকম কাজ হতে পারে তবে আমি অন্য পথে যেতে চাই।
TraceListener
কনসোলের জন্য একটি এবং লগ ফাইলের জন্য একটি ইনস্ট্যান্ট করুন; তারপরে Trace.Write
আপনার কোডটিতে স্টেটমেন্ট ব্যবহার করুন Console.Write
। লগ, বা কনসোল আউটপুট অপসারণ করা বা অন্য লগিং প্রক্রিয়া সংযুক্ত করা সহজ হয়ে যায়।
static void Main(string[] args)
{
Trace.Listeners.Clear();
TextWriterTraceListener twtl = new TextWriterTraceListener(Path.Combine(Path.GetTempPath(), AppDomain.CurrentDomain.FriendlyName));
twtl.Name = "TextLogger";
twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;
ConsoleTraceListener ctl = new ConsoleTraceListener(false);
ctl.TraceOutputOptions = TraceOptions.DateTime;
Trace.Listeners.Add(twtl);
Trace.Listeners.Add(ctl);
Trace.AutoFlush = true;
Trace.WriteLine("The first line to be in the logfile and on the console.");
}
আমি যতদূর মনে করতে পারি, আপনি অ্যাপ্লিকেশন কনফিগারেশনে শ্রোতাদের সংজ্ঞা দিতে পারেন বিল্ডটি স্পর্শ না করে লগিং সক্রিয় বা নিষ্ক্রিয় করা সম্ভব করে তোলে।
এটি একটি সাধারণ শ্রেণি যা টেক্সট রাইটারকে একটি ফাইল এবং কনসোল উভয়কেই ইনপুটটির পুনঃনির্দেশের অনুমতি দেওয়ার জন্য সাবক্লাস করে।
এটি ব্যবহার করুন
using (var cc = new ConsoleCopy("mylogfile.txt"))
{
Console.WriteLine("testing 1-2-3");
Console.WriteLine("testing 4-5-6");
Console.ReadKey();
}
এখানে ক্লাস:
class ConsoleCopy : IDisposable
{
FileStream fileStream;
StreamWriter fileWriter;
TextWriter doubleWriter;
TextWriter oldOut;
class DoubleWriter : TextWriter
{
TextWriter one;
TextWriter two;
public DoubleWriter(TextWriter one, TextWriter two)
{
this.one = one;
this.two = two;
}
public override Encoding Encoding
{
get { return one.Encoding; }
}
public override void Flush()
{
one.Flush();
two.Flush();
}
public override void Write(char value)
{
one.Write(value);
two.Write(value);
}
}
public ConsoleCopy(string path)
{
oldOut = Console.Out;
try
{
fileStream = File.Create(path);
fileWriter = new StreamWriter(fileStream);
fileWriter.AutoFlush = true;
doubleWriter = new DoubleWriter(fileWriter, oldOut);
}
catch (Exception e)
{
Console.WriteLine("Cannot open file for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(doubleWriter);
}
public void Dispose()
{
Console.SetOut(oldOut);
if (fileWriter != null)
{
fileWriter.Flush();
fileWriter.Close();
fileWriter = null;
}
if (fileStream != null)
{
fileStream.Close();
fileStream = null;
}
}
}
Console.WriteLine()
, যা আমি যা চেয়েছিলাম ঠিক সেটাই ছিল।
Console.SetOut(doubleWriter);
। যা কনসোলের জন্য একটি বিশ্বব্যাপী পরিবর্তন করছে, এটি আমাকে খানিকটা সময় নিয়েছে, যেহেতু আমি এমন অ্যাপ্লিকেশনগুলিতে কাজ করতে অভ্যস্ত যেখানে ব্যবহারিকভাবে কিছুই বৈশ্বিক নয়। ভাল জিনিস!
আপনি কি >
কমান্ডটি ব্যবহার করে আউটপুটটিকে কোনও ফাইলে পুনর্নির্দেশ করতে পারবেন না ?
c:\>Console.exe > c:/temp/output.txt
আপনার যদি মিরর দরকার হয় তবে আপনি একটি উইন 32 সংস্করণ সন্ধান করতে পারেন tee
যা কোনও ফাইলের আউটপুটকে বিভক্ত করে।
দেখুন /superuser/74127/tee-for-windows চালানোর জন্য টী বর্ণের নাম PowerShell থেকে
আপনি TextWriter বর্গ উপশ্রেণী পারে, এবং তারপর ব্যবহার Console.Out তার দৃষ্টান্ত ধার্য Console.SetOut পদ্ধতি - যা বিশেষ করে লগ পদ্ধতি উভয় পদ্ধতি একই স্ট্রিং ক্ষণস্থায়ী যেমন একই জিনিস আছে।
অন্য কোনও উপায়ে আপনার নিজস্ব কনসোল শ্রেণির ঘোষণা এবং ক্লাসের মধ্যে পার্থক্য জানাতে ব্যবহারের বিবৃতিটি ব্যবহার করা যেতে পারে:
using Console = My.Very.Own.Little.Console;
আপনার প্রয়োজনীয় স্ট্যান্ডার্ড কনসোলটি অ্যাক্সেস করতে:
global::Console.Whatever
সম্পাদনা: এই পদ্ধতিটি তৃতীয় পক্ষের প্যাকেজ থেকে আসা কনসোলের তথ্য পুনর্নির্দেশের সম্ভাবনা সরবরাহ করে। রাইডলাইন পদ্ধতি ওভাররাইড করা আমার পরিস্থিতির জন্য ভাল তবে আপনার অন্যান্য লিখিত পদ্ধতিগুলি ওভাররাইডের প্রয়োজন হতে পারে তৃতীয় পক্ষের প্যাকেজের উপর নির্ভর করে।
প্রথমে আমাদের স্ট্রিম রাইটার থেকে অন্তর্নিহিত নতুন শ্রেণি তৈরি করা দরকার, কম্বাইন্ড রাইটার বলুন;
তারপরে কনসোল.আউট এর সাথে সম্মিলিত লেখকের একটি নতুন তাত্ক্ষণিক উদ্যোগ নিন;
পরিশেষে আমরা কনসোল আউটপুট কনসোল.সেটআউট দ্বারা নতুন শ্রেণীর তাত্ক্ষণিকে পুনর্নির্দেশ করতে পারি;
নিম্নলিখিত কোডটি আমার জন্য নতুন ক্লাসের কাজ করে।
public class CombinedWriter : StreamWriter
{
TextWriter console;
public CombinedWriter(string path, bool append, Encoding encoding, int bufferSize, TextWriter console)
:base(path, append, encoding, bufferSize)
{
this.console = console;
base.AutoFlush = true; // thanks for @konoplinovich reminding
}
public override void WriteLine(string value)
{
console.Write(value);
base.WriteLine(value);
}
}
public override void Write(char value);
, public override void Write(char[] buffer);
, public override void Write(string value);
এবং public override void Write(char[] buffer, int index, int count);
। অন্যথায় আপনি যদি WriteLine(format, ...)
পদ্ধতিটি ব্যবহার করেন তবে এটি কনসোলে মুদ্রণ করবে না ।
লগ 4 নেট আপনার জন্য এটি করতে পারে। আপনি কেবল এই জাতীয় কিছু লিখবেন:
logger.info("Message");
একটি কনফিগারেশন নির্ধারণ করবে যে মুদ্রণটি কনসোল, ফাইল বা উভয়তে যাবে।
আমি মনে করি আপনি ইতিমধ্যে যা ব্যবহার করছেন তা একদম সেরা পদ্ধতির। আপনার আউটপুটটি মূলত আয়না করার একটি সহজ পদ্ধতি।
প্রথমে একটি গ্লোবাল টেক্সটਰਾਇার শুরুর দিকে ঘোষণা করুন:
private TextWriter txtMirror = new StreamWriter("mirror.txt");
তারপরে লেখার জন্য একটি পদ্ধতি তৈরি করুন:
// Write empty line
private void Log()
{
Console.WriteLine();
txtMirror.WriteLine();
}
// Write text
private void Log(string strText)
{
Console.WriteLine(strText);
txtMirror.WriteLine(strText);
}
এখন, ব্যবহারের পরিবর্তে Console.WriteLine("...");
, ব্যবহার করুন Log("...");
। যে হিসাবে সহজ। এটি আরও খাটো!
আপনি কার্সারপজিশন ( Console.SetCursorPosition(x, y);
) সরিয়ে ফেললে কিছু সমস্যা হতে পারে , তবে অন্যথায় ভাল কাজ করে, আমি নিজেও এটি ব্যবহার করি!
আপনি Console.Write();
কেবল রাইটলাইন ব্যবহার না করলে অবশ্যই আপনি একই পদ্ধতিতে কোনও পদ্ধতি তৈরি করতে পারেন
স্ট্রিম রাইটার থেকে উত্তরাধিকার সূত্রে ক্লাস ব্যবহারের সিদ্ধান্ত, ব্যবহারকারী কিপ থিংকিংয়ের পরামর্শ কার্যকর করে works তবে আমাকে কনস্ট্রাক্টর বেসে যুক্ত করতে হয়েছিল Aআউটফ্লুশ = সত্য:
{
this.console = console;
base.AutoFlush = true;
}
ডেস্ট্রাক্টরের কাছে একটি স্পষ্ট কল а
public new void Dispose ()
{
base.Dispose ();
}
অন্যথায়, তিনি সমস্ত ডেটা রেকর্ড করার আগে ফাইলটি বন্ধ হয়ে যায়।
আমি এটি হিসাবে ব্যবহার করছি:
CombinedWriter cw = new CombinedWriter ( "out.txt", true, Encoding.Unicode, 512, Console.Out );
Console.SetOut (cw);
চমৎকার সমাধানের জন্য চিন্তাভাবনা করার জন্য আপনাকে ধন্যবাদ! আমি কিছু কনসোল রাইটিং ইভেন্টগুলি লগিং এড়াতে আরও কিছু ওভাররাইড যুক্ত করেছি (আমার উদ্দেশ্যে) কেবল কনসোল প্রদর্শনের জন্য প্রত্যাশিত।
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RedirectOutput
{
public class CombinedWriter : StreamWriter
{
TextWriter console;
public CombinedWriter(string path, bool append, TextWriter consoleout)
: base(path, append)
{
this.console = consoleout;
base.AutoFlush = true;
}
public override void Write(string value)
{
console.Write(value);
//base.Write(value);//do not log writes without line ends as these are only for console display
}
public override void WriteLine()
{
console.WriteLine();
//base.WriteLine();//do not log empty writes as these are only for advancing console display
}
public override void WriteLine(string value)
{
console.WriteLine(value);
if (value != "")
{
base.WriteLine(value);
}
}
public new void Dispose()
{
base.Dispose();
}
}
class Program
{
static void Main(string[] args)
{
CombinedWriter cw = new CombinedWriter("combined.log", false, Console.Out);
Console.SetOut(cw);
Console.WriteLine("Line 1");
Console.WriteLine();
Console.WriteLine("Line 2");
Console.WriteLine("");
for (int i = 0; i < 10; i++)
{
Console.Write("Waiting " + i.ToString());
Console.CursorLeft = 0;
}
Console.WriteLine();
for (int i = 0; i < 10; i++)
{
Console.Write("Waiting " + i.ToString());
}
Console.WriteLine();
Console.WriteLine("Line 3");
cw.Dispose();
}
}
}
আপনি যদি নিয়ন্ত্রণ করেন না এমন কোনও কোড থেকে কনসোল আউটপুট সদৃশ করেন, উদাহরণস্বরূপ তৃতীয় পক্ষের লাইব্রেরি, পাঠ্য লেখকের সমস্ত সদস্যকে ওভাররাইট করা উচিত। কোডটি এই থ্রেড থেকে আইডিয়া ব্যবহার করে।
ব্যবহার:
using (StreamWriter writer = new StreamWriter(filePath))
{
using (new ConsoleMirroring(writer))
{
// code using console output
}
}
কনসোলমিররিং ক্লাস
public class ConsoleMirroring : TextWriter
{
private TextWriter _consoleOutput;
private TextWriter _consoleError;
private StreamWriter _streamWriter;
public ConsoleMirroring(StreamWriter streamWriter)
{
this._streamWriter = streamWriter;
_consoleOutput = Console.Out;
_consoleError = Console.Error;
Console.SetOut(this);
Console.SetError(this);
}
public override Encoding Encoding { get { return _consoleOutput.Encoding; } }
public override IFormatProvider FormatProvider { get { return _consoleOutput.FormatProvider; } }
public override string NewLine { get { return _consoleOutput.NewLine; } set { _consoleOutput.NewLine = value; } }
public override void Close()
{
_consoleOutput.Close();
_streamWriter.Close();
}
public override void Flush()
{
_consoleOutput.Flush();
_streamWriter.Flush();
}
public override void Write(double value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(string value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(object value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(decimal value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(float value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(bool value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(int value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(uint value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(ulong value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(long value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(char[] buffer)
{
_consoleOutput.Write(buffer);
_streamWriter.Write(buffer);
}
public override void Write(char value)
{
_consoleOutput.Write(value);
_streamWriter.Write(value);
}
public override void Write(string format, params object[] arg)
{
_consoleOutput.Write(format, arg);
_streamWriter.Write(format, arg);
}
public override void Write(string format, object arg0)
{
_consoleOutput.Write(format, arg0);
_streamWriter.Write(format, arg0);
}
public override void Write(string format, object arg0, object arg1)
{
_consoleOutput.Write(format, arg0, arg1);
_streamWriter.Write(format, arg0, arg1);
}
public override void Write(char[] buffer, int index, int count)
{
_consoleOutput.Write(buffer, index, count);
_streamWriter.Write(buffer, index, count);
}
public override void Write(string format, object arg0, object arg1, object arg2)
{
_consoleOutput.Write(format, arg0, arg1, arg2);
_streamWriter.Write(format, arg0, arg1, arg2);
}
public override void WriteLine()
{
_consoleOutput.WriteLine();
_streamWriter.WriteLine();
}
public override void WriteLine(double value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(decimal value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(string value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(object value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(float value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(bool value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(uint value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(long value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(ulong value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(int value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(char[] buffer)
{
_consoleOutput.WriteLine(buffer);
_streamWriter.WriteLine(buffer);
}
public override void WriteLine(char value)
{
_consoleOutput.WriteLine(value);
_streamWriter.WriteLine(value);
}
public override void WriteLine(string format, params object[] arg)
{
_consoleOutput.WriteLine(format, arg);
_streamWriter.WriteLine(format, arg);
}
public override void WriteLine(string format, object arg0)
{
_consoleOutput.WriteLine(format, arg0);
_streamWriter.WriteLine(format, arg0);
}
public override void WriteLine(string format, object arg0, object arg1)
{
_consoleOutput.WriteLine(format, arg0, arg1);
_streamWriter.WriteLine(format, arg0, arg1);
}
public override void WriteLine(char[] buffer, int index, int count)
{
_consoleOutput.WriteLine(buffer, index, count);
_streamWriter.WriteLine(buffer, index, count);
}
public override void WriteLine(string format, object arg0, object arg1, object arg2)
{
_consoleOutput.WriteLine(format, arg0, arg1, arg2);
_streamWriter.WriteLine(format, arg0, arg1, arg2);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Console.SetOut(_consoleOutput);
Console.SetError(_consoleError);
}
}
}
আপনি টেক্সট রাইটার থেকে উত্তরাধিকারসূত্রে প্রাপ্ত নিজস্ব শ্রেণীর প্রয়োগ করে রাইটলাইন পদ্ধতিকে ওভাররাইড করে কনসোলের স্বচ্ছ প্রতিচ্ছবি তৈরি করতে পারেন ut
রাইটলাইনে আপনি এটি ট্রেসকে লিখতে পারেন যা ফাইলটিতে লিখতে কনফিগার করা যেতে পারে।
আমি এই উত্তরটি খুব সহায়ক বলে খুঁজে পেয়েছি: https://stackoverflow.com/a/10918320/379132
এটি আসলে আমার পক্ষে কাজ করেছিল!
আমার উত্তর সর্বাধিক ভোটপ্রাপ্ত অ-গৃহীত উত্তরের উপর ভিত্তি করে এবং সর্বনিম্ন-ভোট প্রাপ্ত উত্তরও যা আমি মনে করি এটি এখন পর্যন্ত সবচেয়ে মার্জিত সমাধান। আপনি যে স্ট্রিম টাইপটি ব্যবহার করতে পারেন তার ক্ষেত্রে এটি একটু বেশি জেনেরিক ( MemoryStream
উদাহরণস্বরূপ আপনি একটি ব্যবহার করতে পারেন ) তবে আমি ব্রেভিটির উত্তরগুলির উত্তরগুলিতে অন্তর্ভুক্ত সমস্ত বর্ধিত কার্যকারিতা বাদ দিয়েছি ।
class ConsoleMirrorWriter : TextWriter
{
private readonly StreamWriter _writer;
private readonly TextWriter _consoleOut;
public ConsoleMirrorWriter(Stream stream)
{
_writer = new StreamWriter(stream);
_consoleOut = Console.Out;
Console.SetOut(this);
}
public override Encoding Encoding => _writer.Encoding;
public override void Flush()
{
_writer.Flush();
_consoleOut.Flush();
}
public override void Write(char value)
{
_writer.Write(value);
_consoleOut.Write(value);
}
protected override void Dispose(bool disposing)
{
if (!disposing) return;
_writer.Dispose();
Console.SetOut(_consoleOut);
}
}
ব্যবহার:
using (var stream = File.Create(Path.Combine(Path.GetTempPath(), AppDomain.CurrentDomain.FriendlyName)))
using (var writer = new ConsoleMirrorWriter(stream))
{
// Code using console output.
}