Page 1 of 1

πρόβλημα με new line σε OutputStreamWriter

Posted: Fri Dec 07, 2007 10:11 pm
by Zifnab
Όταν βάζω newline /n μέσα στο write της συγκεκριμένης class απλά δεν με υπακούει και το παρακάμπτει...Με άλλα λόγια δεν βρίσκω τρόπο να αλλάξω γραμμή.Παρακαλώ μην μου προτείνετε να αλλάξω class γιατί πολύ απλά η απορία μου είναι γιατί συμβαίνει με την συγκεκριμένη.

Code: Select all

import java.io.*;
import java.util.Date;
public class Main {
    public static void main(String[] args) throws IOException  {

          StringBuffer strbuf=new StringBuffer(10);
          strbuf.append("blabla"); 
          File file = new File("test.txt");
          FileOutputStream fs = new FileOutputStream(file,true); 
          OutputStreamWriter osw = new OutputStreamWriter(fs);
          Date date = new Date();
          osw.append('\n');
          osw.write(strbuf.toString()+date.toString());
          osw.flush();
     }
}
Ότι και να κάνω ακόμα δλδ γράφω append/write ή ακόμα και πολλά /n μαζί
και τπτ. Ή ακόμα και write("33333\n\n\n\n44444"); μου βγάζει 3333344444 κολλητά :???:

Posted: Fri Dec 07, 2007 10:57 pm
by StormRider

Code: Select all

String lineSep = System.getProperty("line.separator"); 
Μου φαίνεται με αυτό θα κάνεις τη δουλειά σου.
Απλά πρόσθεσε το lineSep εκεί που θες.

Posted: Sat Dec 08, 2007 1:05 am
by Zifnab
wow Δούλεψε thnx :-D ! Αν ήξερες να μου πεις τί τον χάλαγε το \n σαν string ή σαν χαρακτήρα θα σου ήμουν ευγνώμων...

Posted: Sat Dec 08, 2007 1:20 am
by sandra
κ.συντονιστά το είχαμε ξανασυναντήσει εδώ το πρόβλημα. Κάτι με τα windows παίζει...

Posted: Sat Dec 08, 2007 1:28 am
by Zifnab
'εδώ' που ακριβώς ?! :shock: βασικά πρέπει εσωτερικά να κάνει αναπροσαρμογή του string και να πετάει τα newline ....
Δεν ξέρω...

Posted: Sat Dec 08, 2007 1:39 am
by StormRider
:-) Δεν παίζει κάτι περίεργο με τα Windows... απλά τα windows -in general- για eol(end-of-line) character χρησιμοποιούν τον "\r\n" character, το Unix "\n" και το Mac τον "\r"...

Αυτό που κάνει η System.getProperty("line.separator"); είναι να "ζητήσει" από το OS να επιστρέψει ποιον χαρακτήρα χρησιμοποιεί για αλλαγή γραμμής!

Παρατήρησε όμως κάποια περίεργα points:
-Αν γράψεις \n και το ανοίξεις με WordPad or Textpad θα το δεις όπως το περιμένεις το output.
-Aν τρέξεις το πρόγραμμα στα Windows και στείλεις το output σε ένα unix σύστημα τότε ενδέχεται να δείς ξεκάρφωτα "\r" στο output σου

Γενικά διαλέγεις και παίρνεις! Δεν είναι πανάκεια ο line.separator... δεν πρέπει να υπάρχει κάτι που να καλύπτει όλες τις περιπτώσεις...

Όταν βέβαια χρησιμοποιείς το System.out.println(); και βάζεις ειδικούς χαρακτήρες, εκεί φροντίζει η Java για εσένα να βρεί τον eol char για το σύστημα στο οποίο τρέχει το πρόγραμμά σου.

edit: Όταν το είχα πρωτοχρησιμοποιήσει μου το χε πεί η sandra σε κάποιες από εκείνες τις σελίδες του "Προγραμματισμός με Java", σε κάποια από τις προηγούμενες σελίδες από το λινκ που έδωσε πρέπει να είναι

Posted: Sat Dec 08, 2007 1:42 am
by Zifnab
χμ ενδιαφέρον ! thnx StormRider και πάλ ι ;) Αν και θα προτιμούσα η java είτε να μην κάνει τίποτα δλδ να μην μετατρέπει τα \n σε \r ή \r\n είτε να το κάνει παντού δλδ και στο OutputStreamWriter....Πως φαίνεται ότι η java έχει φτιαχτεί από χιλιάδες διαφορετικούς προγραμματιστές :lol: :lol:

Posted: Sat Dec 08, 2007 1:45 am
by StormRider
Προφανώς ναι... μάλλον όχι προφανώς, δεν ξέρω ακριβώς την υλοποίηση, αλλά πρέπει να κάνει υπερφόρτωση των ειδικών χαρακτήρων... δλδ το \n να το παίρνει μέσω της .getProperty("line.separator");

Posted: Sat Dec 08, 2007 1:46 am
by cactus
Εμέ μου δούλεψε μια χαρά αυτό που έγραψε ο Zifnab στο 1ο ποστ...μου άλαξε και γραμμη, και για να είμαι σίγουρος έβαλα πολύ πράμα, δεν βλέπω πρόβλημα.

anyway, η sun προτείνει:
For top efficiency, consider wrapping an OutputStreamWriter within a BufferedWriter so as to avoid frequent converter invocations. For example:

Writer out
= new BufferedWriter(new OutputStreamWriter(System.out));
edit
windows τρέχω

Posted: Sat Dec 08, 2007 1:55 am
by StormRider
@cactus: εχεις vista? λες να άλλαξαν τους eol chars? :) αν είχα θα δοκίμαζα... πάντως κατα κύριο λόγο ισχύει Win:"\r\n", Unix "\n" , Mac: "\r" (το χα ψάξει τότε που το χα πρωτοσυναντήσει)

Ας το δοκιμάσει κάποιος στο dia ή σε linux(αν και δεν ξέρω κατά πόσο το έχει κληρονονομήσει από τo unix)

Posted: Sat Dec 08, 2007 1:56 am
by Zifnab
εγώ σε vista τρέχω σε NetBeans ide 6.0 συγκεκριμένα.... To vm της java μήπως άλλαξε?! μπα... :???:

Posted: Sat Dec 08, 2007 1:58 am
by cactus
StormRider wrote:@cactus: εχεις vista?
xp έχω.

Αλλά όσα προγράμματα έχω γράψει πάντα \n χρησιμοποιώ και ποτέ δεν είχα πρόβλημα.
Τέλος πάντων συμβαίνουν και περίεργα φαίνεται.

Posted: Sat Dec 08, 2007 2:03 am
by StormRider
Είναι τόσο περίεργο όμως...
Και εγώ xp sp2, με Eclipse και jre1.6.0_01...
Σίγουρα το ανοίγεις με notepad ή χρησιμοποιείς κανα ultraedit or notepad++ ??

Posted: Sat Dec 08, 2007 2:10 am
by cactus
@StormRider
Μισό, τι εννοείς δεν βλέπεις αλλαγή γραμμή;
εννοείς ότι στο notepadδεν σου άλλαξε γραμμή ή ότι δεν βλέπεις αυτό το όρθιοπαραλληλόγραμμο μετά τη λέξη σου.
Η java χρησιμοποιεί unicode(τι άθλια που το έθεσα, δεν ξέρω να το πω καλύτερα), δεν θα αλλάξει γραμμή στο notepad αλλά θα δεις ένα όρθιο παραληλόγραμμο ακριβώς μετά το γράμμα που έβαλες το '\n'. Και \r να βάλω πάλι τα ίδια.

Αν το βλέπεις όλα οκ. Αν όχι τότε έιναι περίεργο.

Posted: Sat Dec 08, 2007 2:28 am
by HdkiLLeR
Λοιπόν μισό γιατι υπάρχουν δύο πράγματα εδώ. Άλλο τι γράφεις και άλλο τι βλέπεις και νομίζεις ότι έγραψες. Γράφεις \nblabla στο file αυτό είναι δεδομένο*. Το θέμα είναι πως πας να δεις εάν το έχεις γράψει όντως αυτό; Με κάποιον text editor (πχ notepad); Εάν ναι τότε το Notepad, αλλά και όλοι οι windows based text editors, για να αλλάξουν γραμμή περιμένουν το \r\n και όχι το \n μόνο του (προφανώς και δεν το βλέπεις γιατί ο χαρακτήρας \n δεν είναι printable). Αυτό δεν σημαίνει ότι δεν είναι εκεί. Εάν πάρεις το file.txt και το πας σε ένα unix based σύστημα και το δεις εκεί με έναν editor θα δεις ότι θα αλλάξει κανονικά line.

*:
Δοκίμασε αυτό:

Code: Select all

import java.io.*;
import java.util.Date;
public class Main {
    public static void main(String[] args) throws IOException  {

          StringBuffer strbuf=new StringBuffer(10);
          strbuf.append("blabla");
          File file = new File("test.txt");
          FileOutputStream fs = new FileOutputStream(file,true);
          OutputStreamWriter osw = new OutputStreamWriter(fs);
          Date date = new Date();
          osw.append('\n');
          osw.write(strbuf.toString());
          osw.flush();
     }
}
αν και εσύ μπορεί να βλέπεις blabla μέσα σε ένα file, δες το μέγεθος του. Πρέπει να είναι 7 bytes. Εάν ναι τότε έχει γραφτεί μέσα το: \nblabla άσχετα εάν εσύ δεν το βλέπεις.

Posted: Sat Dec 08, 2007 2:37 am
by StormRider
Εννοώ ότι δεν αλλάζει γραμμή...
Ναι, βγάζει το σηματάκι του παραλληλογραμου (εκεί που βάζω το \n) αλλά δεν αλλάζει γραμμή...
Αντικατέστησα το "\n" με το "\r\n" και όντως αλλάζει γραμμή!... άρα τα win έχουν end-of-line char τον "\r\n", αντιστοιχεί δλδ στο CR-LF combination.

@Microsoft: δώστε μας τον source code να δούμε τί παίζει!!! :Ρ

Edit: nice HdkiLLeR!

Posted: Sat Dec 08, 2007 4:08 am
by elsupreme
HdKiller, σου ξέφυγε το Date :-p

Posted: Sat Dec 08, 2007 10:43 am
by Zifnab
Hd ευχαριστώ για το explanation. Κάτι αντίστοιχο τελευταίο. Στο cmd ή τέλος πάντων στην embedded console του NetBeans αλλάζει με το \n ή απλά γίνεται μετατροπή όπως λέγαμε πιο πρίν?

Επίσης το λειτουργικό είναι εκείνο που όταν δώσω εγώ input Enter θα το μεταφράσει σε \n ή \r ή \r\n για να το γράψει π.χ σε ένα αρχείο?

Posted: Sat Dec 08, 2007 12:58 pm
by HdkiLLeR
StormRider wrote: Αντικατέστησα το "\n" με το "\r\n" και όντως αλλάζει γραμμή!... άρα τα win έχουν end-of-line char τον "\r\n", αντιστοιχεί δλδ στο CR-LF combination.
Ναι έτσι είναι, η αλλαγή γραμμής είναι δύο χαρακτήρες στα Windows και δεν μπορείς να κάνεις κάτι γι' αυτό :) :). Υπάρχουν και πολλά utils και σε Linux/Unix αλλά και σε Windows για τις μετατροπές text απο το ένα OS στο άλλο.
Zifnab wrote:Hd ευχαριστώ για το explanation. Κάτι αντίστοιχο τελευταίο. Στο cmd ή τέλος πάντων στην embedded console του NetBeans αλλάζει με το \n ή απλά γίνεται μετατροπή όπως λέγαμε πιο πρίν?

Επίσης το λειτουργικό είναι εκείνο που όταν δώσω εγώ input Enter θα το μεταφράσει σε \n ή \r ή \r\n για να το γράψει π.χ σε ένα αρχείο?
To Netbeans έχει δικό του "console" οπότε φροντίζει να τα τυπώνει σωστά. Τώρα σχετικά με την άλλη σου ερώτηση ναι. To ΟS παίρνει το interrupt απο τον Keyboard Controller και διαβάζει μια τιμή (την τιμή που αντιστοιχεί στο Key που πάτησες) απο έναν buffer του KBC*. Απο εκεί και πέρα μεταφράζει την τιμή αυτή σε ένα χαρακτήρα ή και σε συνδιασμό αυτών.

*: Βασικά είναι λίγο διοαφορετικό κάνει ένα πιο έξυπνο κόλπο για να πιάνει και multiple keys pressed κλπ κλπ. Δεν είναι δηλαδή απλό serial interface..πατάω κουμπί μπαίνει σε μια ουρά και απο την κεφαλή της διαβάζει το OS ανάλογα με τα interrupts που σκάνε.
elsupreme wrote:HdKiller, σου ξέφυγε το Date :-p
Ναι αλλά εάν σκεφτείς ότι καλούμε το JVM με default parameters και το heap size είναι minimum τότε δεν θα το θυμηθεί ο garbage collector σύντομα :-p

Posted: Sun Dec 09, 2007 4:01 am
by elsupreme
Σόρρυ που θα πάει μακριά αυτό - εννοούσα ότι ξέχασες :

Code: Select all

osw.write(strbuf.toString()+date.toString()); 
(Τώρα, αν αυτό που μου απάντησες αναφερόταν στο αμέσως επάνω, η εξήγηση με το garbage collector θέλει παραπάνω εξήγηση φοβάμαι...)

Posted: Mon Dec 10, 2007 7:16 pm
by HdkiLLeR
elsupreme wrote:Σόρρυ που θα πάει μακριά αυτό - εννοούσα ότι ξέχασες :

Code: Select all

osw.write(strbuf.toString()+date.toString()); 
(Τώρα, αν αυτό που μου απάντησες αναφερόταν στο αμέσως επάνω, η εξήγηση με το garbage collector θέλει παραπάνω εξήγηση φοβάμαι...)
Lol μου αρέσει να το τραβάμε για τέτοια θέματα :)

Αυτό που έλεγα, ή μάλλον υπονοούσα, είναι ότι παρά το γεγονός ότι το ξέχασα να το βάλω στο stream άφησα και την αρχικοποίηση του (Date date = new Date()), οπότε ουσιαστικά θα γίνει ένα allocation το οποίο δεν θα χρησιμοποιηθεί ποτέ (θα δεσμευτεί χώρος στο heap για το object date). Δεν πειράζει όμως γιατί eventually the gc will come to clean the mess :)

Posted: Wed Dec 12, 2007 2:01 am
by The Punisher
Η συζήτηση περί Garbage Collector μετακινήθηκε εδώ