2009-06-18 9 views
6

जावा में, ज़ाहिर है। मैं एक प्रोग्राम लिख रहा हूं और इसे विंडोज वातावरण के तहत चला रहा हूं, लेकिन मुझे यूनिक्स प्रारूप में आउटपुट (.csv) करने की आवश्यकता है। कोई आसान समाधान? धन्यवाद!क्या यूनिक्स प्रारूप में प्रिंटवाइटर आउटपुट बनाने का कोई तरीका है?

+1

आप यूनिक्स प्रारूप के साथ क्या मतलब है ऊपर लिख? लाइन एंडिंग प्रारूप? – jitter

उत्तर

14

"यूनिक्स प्रारूप" द्वारा आपका मतलब है "\ n" "\ r \ n" के बजाय लाइन टर्मिनेटर के रूप में? प्रिंटवाइटर बनाने से पहले बस line.separator सिस्टम प्रॉपर्टी सेट करें।

बस एक डेमो के रूप

:

import java.io.*; 

public class Test 
{ 
    public static void main(String[] args) 
     throws Exception // Just for simplicity 
    { 
     System.setProperty("line.separator", "xxx"); 
     PrintWriter pw = new PrintWriter(System.out); 
     pw.println("foo"); 
     pw.println("bar"); 
     pw.flush(); 
    } 
} 
पाठ्यक्रम है कि यह पूरे JVM, जो आदर्श नहीं है के लिए सेट की

, लेकिन यह आप सभी की जरूरत के लिए हो हो सकता है।

+0

बढ़िया, धन्यवाद! – Monster

3

स्वरूपण मुद्दा आप के लिए है कि विंडोज पंक्ति विराम कैरिज वापसी लाइन फ़ीड ("\r\n") यूनिक्स होते हैं, जबकि लाइन फ़ीड ("\n") कर रहे हैं केवल, सबसे आसान तरीका है कि आपकी फ़ाइल वामो का उपयोग करता है बनाने के लिए उल्लेख मान लिया जाये और नहीं CRLF है println eschew करने के लिए और इसके बजाय लाइनों को समाप्त करने के लिए print("\n") का उपयोग करें।

तो बजाय:

writer.println("foo,bar,88"); 

उपयोग

writer.print("foo,bar,88\n"); 

println सुनिश्चित करें कि आप उन सब को पकड़ने के लिए बनाने के लिए तुम सिर्फ प्रासंगिक फ़ाइलें खोज सकते हैं।

+0

इस दृष्टिकोण और जॉन स्कीट के बीच का अंतर यह है कि वह वैश्विक है, लेकिन इसमें कम बदलाव की आवश्यकता है। जब तक आप सुनिश्चित न हों कि आपको कोई परवाह नहीं है कि आपके प्रोग्राम में सबकुछ \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ – Zarkonnen

+0

आह, मैं देखता हूं। उत्कृष्ट विचार भी। हालांकि मेरे मामले में (हालांकि मुझे निर्दिष्ट होना चाहिए था), मैं एक वैश्विक दृष्टिकोण की तलाश में हूं। धन्यवाद! – Monster

2

एक परावर्तक प्रोग्रामर सिस्टम प्रॉपर्टी ऑब्जेक्ट पर सिंक्रनाइज़ करेगा, कम से कम अगर विभिन्न प्रिंटराइटर को विभिन्न प्रकार के लाइन टर्मिनेटर की आवश्यकता होती है।

public static PrintWriter createPrintWriter(OutputStreamWriter out, boolean autoflush){ 
    Properties props = System.getProperties(); 
    synchronized (props) { 
     Object old = null; 
     try { 
     old = props.setProperty("line.separator", "\n"); 
     return new PrintWriter(out, autoflush); 
     } finally { 
      if(old != null) { 
       props.put("line.separator", old); 
      } 
     } 
    } 
} 
+0

यहां तर्क क्या है :)? –

+2

यह सुनिश्चित करने के लिए कि आपको वास्तव में वह संपत्ति मिल जाएगी जो आपने अभी सेट की है, जब तक कि आप एक थ्रेड में नहीं चल रहे हों, या हमेशा एक ही लाइन टर्मिनेटर का उपयोग करेंगे, और यह कभी भी नहीं बदला जा रहा है। – KarlP

+0

दुर्भाग्यवश यह इस लॉक का उपयोग किए बिना संपत्ति को एक साथ बदलने के लिए किसी अन्य विधि को रोकता नहीं है। –

8

यूनिक्स लाइन अंत के साथ एक फ़ाइल लिखने के लिए, एक वर्ग PrintWriter से व्युत्पन्न में println ओवरराइड, और \ n के साथ प्रिंट का उपयोग करें।

PrintWriter out = new PrintWriter("testFile") { 
    @Override 
    public void println() { 
     write('\n'); 
    } 
}; 
out.println("This file will always have unix line endings"); 
out.println(41); 
out.close(); 

यह आपके कोड में मौजूद किसी मौजूदा प्रिंटल कॉल को स्पर्श करने से बचाता है।

+0

नहीं, आपको सिर्फ 'println() 'को ओवरराइड करना चाहिए। अन्य सभी println विधियों (जैसे 'println (स्ट्रिंग)', 'println (int)', आदि को डेटा प्रिंट करने और फिर 'println()' को कॉल करने के रूप में दस्तावेज किया गया है। साथ ही, आपको संरक्षित चर 'लॉक' पर सिंक्रनाइज़ करना चाहिए –

+0

फेयर प्वाइंट, ओवरलैडिंग println() एक बेहतर विचार है। मैंने अपना कोड अपडेट किया है। 'लिखने' के लिए कॉल लॉक को संभालती है। –

1

मुझे 2 और विकल्प दिखाई देते हैं जो पूरे सिस्टम को प्रभावित नहीं करते हैं या lineSeparator सेट करने जैसी समवर्ती प्रॉपल्म्स का नेतृत्व करते हैं। मैं एक एनम भी घोषित करता हूं जो रेखा के अंत का प्रतिनिधित्व करता है।

enum LineEnding { 
    UNIX("\n"), DOS("\r\n"); 

    private String lineSeparator; 

    LineEnding(String lineSeparator) { 
    this.lineSeparator = lineSeparator; 
    } 

    public String getLineSeparator() { 
    return lineSeparator; 
    } 
} 
  1. lineSeperator प्रतिबिंब का उपयोग कर सेट करें।

    आपको ऐसे कारखाने को बनाना चाहिए जो क्लाइंट से प्रिंटवाइटर आंतरिक छिपाने के लिए प्रतिबिंब का उपयोग करके पहुंच को समाहित कर ले। जैसे ग्राहक कोड इस तरह दिखना चाहिए: क्रियान्वयन ऐसा दिखाई दे सकता है

    PrintWriterFactory.newPrintWriter(someWriter, LineEnding.UNIX); 
    

    जबकि:

    public class PrintWriterFactory { 
    
        private static final Field lineSeparatorField; 
    
        static { 
        try { 
         lineSeparatorField = PrintWriter.class.getDeclaredField("lineSeparator"); 
         lineSeparatorField.setAccessible(true); 
        } catch (NoSuchFieldException e) { 
         throw new IllegalStateException("java.io.PrintWriter implementation changed. Unable to determine lineSeparator field.", e); 
        } 
        } 
    
        public static PrintWriter newPrintWriter(Writer writer, LineEnding lineEnding) { 
        PrintWriter printWriter = new PrintWriter(writer); 
    
        try { 
         lineSeparatorField.set(printWriter, lineEnding.getLineSeparator()); 
        } catch (IllegalAccessException e) { 
         throw new IllegalStateException("Can't set line ending", e); 
        } 
    
        return printWriter; 
        } 
    } 
    

    पुनश्च: कारखाने स्थिर नहीं होना चाहिए। यदि आप PrintWriter कार्यान्वयन एक जेडीके से दूसरे में कार्यान्वयन में परिवर्तन करते हैं तो आप एक इंटरफ़ेस और एकाधिक कार्यान्वयन का उपयोग कर सकते हैं और इस प्रकार आपको एक और प्रतिबिंब रणनीति का उपयोग करना होगा।

  2. PrintWriter बढ़ाएँ और println() विधि

    public class LineEndingPrintWriter extends PrintWriter { 
    
        protected boolean autoFlush = false; 
        private LineEnding lineEnding; 
    
        public LineEndingPrintWriter(Writer out, LineEnding lineEnding) { 
        this(out, false, lineEnding); 
        } 
    
        public LineEndingPrintWriter(Writer out, boolean autoFlush, LineEnding lineEnding) { 
        super(out, autoFlush); 
        this.autoFlush = autoFlush; 
        this.lineEnding = lineEnding; 
        } 
    
        public LineEndingPrintWriter(OutputStream out, LineEnding lineEnding) { 
        this(out, false, lineEnding); 
        } 
    
        public LineEndingPrintWriter(OutputStream out, boolean autoFlush, LineEnding lineEnding) { 
        super(out, autoFlush); 
        this.autoFlush = autoFlush; 
        this.lineEnding = lineEnding; 
        } 
    
        protected void ensureOpen() throws IOException { 
        if (out == null) 
         throw new IOException("Stream closed"); 
        } 
    
        public void println() { 
        // Method body taken from java.io.PrintWriter.println(); 
        try { 
         synchronized (lock) { 
         ensureOpen(); 
    
         out.write(lineEnding.getLineSeparator()); 
    
         if (autoFlush) { 
          out.flush(); 
         } 
         } 
        } catch (InterruptedIOException e) { 
         Thread.currentThread().interrupt(); 
        } catch (IOException e) { 
         setError(); 
        } 
        } 
    } 
    
संबंधित मुद्दे