2010-07-27 2 views
27

के बाद असली STDOUT को लिखना मैं System.out और System.err को अवरुद्ध करने की कोशिश कर रहा हूं, लेकिन जब आवश्यक हो तो मूल धाराओं को लिखने की क्षमता बनाए रखता हूं।जावा: System.setOut

PrintStream ps = System.out; 
System.setOut(new MyMagicPrintStream()); 
ps.println("foo"); 

दुर्भाग्य से, सिस्टम वर्ग 'कार्यान्वयन के विवरण का मतलब है मेरे उदाहरण में, "foo" असली stdout के instread MyMagicPrintStream लिए भेजा जाता है। क्या किसी को असली/मूल आउटपुटस्ट्रीम के संदर्भ प्राप्त करने के बारे में पता है।

धन्यवाद!

पीएस: अन्यथा इसका परिणाम एसईओ के लिए एक स्टैक ओवरफ्लो एरर < में होगा।

उत्तर

29

कोशिश यह:

PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out)) 
+1

(मैं आप ऐसा कर सकता है पता नहीं था!) हालांकि, इस दृष्टिकोण के साथ एक संभावित समस्या है। यदि आपके एप्लिकेशन का कोई अन्य हिस्सा मूल सिस्टम का उपयोग कर रहा है। 'प्रिंटस्ट्रीम' ऑब्जेक्ट के बाहर, तो दो धाराओं से stdout आउटपुट को यादृच्छिक रूप से interleaved किया जा सकता है। एक स्ट्रीम ऑब्जेक्ट का उपयोग करना इससे कम प्रवण होगा। –

+0

मुझे लगता है कि ऐसा नहीं होगा क्योंकि प्रिंटस्ट्रीम में बफर नहीं हैं इसलिए डेटा सीधे stdout पर आना चाहिए, है ना? – fqsxr

+1

मुझे पता था कि मूल फ़ाइल डिस्क्रिप्टर प्राप्त करने का एक तरीका होना चाहिए। यह पूर्ण है। धन्यवाद! – Jim

13

कुछ इस तरह का प्रयास करें:

PrintStream original = new PrintStream(System.out); 

    // replace the System.out, here I redirect to NUL 
    System.setOut(new PrintStream(new FileOutputStream("NUL:"))); 
    System.out.println("bar"); // no output 

    // the original stream is still available 
    original.println("foo"); // output to stdout 
+0

ओपी पोस्ट करने के लिए यह अलग कैसे है? – cletus

+0

ओपी एक संदर्भ रखता है जिसे setOut() द्वारा बदला जाएगा। मेरे जवाब में, मैं वर्तमान आउट से एक नया स्ट्रीम तैयार करता हूं जो setOut() से प्रभावित नहीं होगा। कम से कम, मैं इसे समझता हूं :-) – RealHowTo

+0

वाह, मैं प्रभावित हूं। मैंने जेवीएम के माध्यम से पूरी तरह से यह उम्मीद की कि यह मेरे ओपी के रूप में विफल हो जाए, लेकिन यह काम करता है। बधाई, यह प्रभावशाली है। धन्यवाद! – Jim

2
PrintStream original = System.out; 
System.setOut(new MyMagicPrintStream()); 

// This will print to MyMagicPrintStream(); 
System.out.println("foo for MyMagicPrintStream"); 


System.setOut(original); 

// This will print to original print stream; 
System.out.println("foo for original print stream (stdout)"); 

यह मेरे लिए काम करता है।

+0

मेरे लिए काम नहीं करता है। – dgrant

+0

मेरे लिए भी काम नहीं किया; इच्छा है कि यह किया। – Kelly

+0

मेरे लिए काम करता है – edwardmp

1

PrintStream original = new PrintStream(System.out); मूल रूप से मौजूदा संदर्भ को लपेटता है - इसलिए यदि System.setOut() इसे बदल रहा था - इसमें कोई अंतर नहीं होना चाहिए। यह शायद विशेष जेवीएम के साथ एक मुद्दा है, लेकिन मुझे लगता है कि MyMagicPrintStream, या stdout पर कोड लेखन के साथ कुछ गलत था। असल में कोड का टुकड़ा निम्नलिखित वास्तव में क्या विंडोज के लिए सूर्य 1.6.0_20-B02 पर उम्मीद है करता है:

import java.io.FileOutputStream; 
import java.io.PrintStream; 

public class SystemOutTest { 

public static void main(String args[]) { 
    try { 
     PrintStream ps = System.out; 
     System.setOut(new PrintStream(new FileOutputStream("stdout.log"))); 

     System.out.println("foo"); 
     ps.println("bar"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

} 

"foo" stdout.log लिए कंसोल के लिए, "बार" चला जाता है।

इसके अलावा, आप का उपयोग करने की जरूरत है मूल stdin/बाहर JVM स्टार्टअप की सौंपा - आप System.console(); उपयोग कर सकते हैं (बस याद है - यह null हो सकता है!)