2016-07-14 6 views
0

So funktioniert mein Code gut, wenn Sie von Eclipse ausgeführt wird, aber Ausführen des runnable Jar des Projekts nicht.java jar schreibt in zwei verschiedene Zeichencodierung

Hier ist mein Code:

import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.nio.file.StandardOpenOption; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
import java.util.stream.Collectors; 


public class cc { 

    public static HttpURLConnection con; 
    public static String url = "http://bac.onec.dz/index.php"; 
    public static int begin; 
    public static int max; 
    public static boolean paused=false; 
    public static String path="result.csv"; 

    public static void setData(int b,int m){ 
     begin=b;max=m; 
    } 
    public static void main(String[] args) throws Exception { 
      int i =1; 
      setData(35043487,2); 
      while (i<=max && !paused) { 
      sendPost(begin++); 
      i++; 
     } 
    } 

    private static void sendPost(int mat) throws Exception { 
     String urlParameters ; 
     URL obj = new URL(url); 
     BufferedReader in; 
     StringBuffer response; 

     con = (HttpURLConnection) obj.openConnection(); 
     con.setRequestMethod("POST"); 
     con.setRequestProperty("Host", "bac.onec.dz"); 
     con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"); 
     con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); 
     con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 
     con.setRequestProperty("Accept-Encoding", "gzip, deflate"); 
     con.setRequestProperty("Referer", "http://bac.onec.dz/"); 
     con.setRequestProperty("Cookie", "bbbbbbbbbbbbbbb=ANNCLHAEAAAAAAAAJHKBHDAAAAAAAAAAEADAOFFHFHFHAAAADAAANKIFFKIFAAAA; TS1ff960=20859ee226968392c837af0430f21cf0087e23d48701410f5785a62879b49ee6533a75145e5dca68b041d236; aaaaaaaaaaaaaaa=GAABBCCHICBGBAAECAAAAAKCHHAAAAAAEACAALAAKGFHAAAADAAAAGAACKIFAAAA"); 
     con.setDoOutput(true); 
     urlParameters = "matriculebac="+mat+"&dobac=%D8%A7%D8%B3%D8%AA%D8%B8%D9%87%D8%A7%D8%B1+%D8%A7%D9%84%D9%86%D8%AA%D9%8A%D8%AC%D8%A9"; 

     DataOutputStream wr = new DataOutputStream(con.getOutputStream()); 
      wr.writeBytes(urlParameters); 
      wr.flush(); 
      wr.close(); 
     in = new BufferedReader(new InputStreamReader(con.getInputStream())); 
     response = new StringBuffer();  
     Object[] aa = in.lines().toArray(); 

     for (Object object : aa) response.append(object.toString()+"\n"); 
     in.close(); 

     Pattern pattern = Pattern.compile("alert\\(.*?\\);"); 
     Matcher matcher = pattern.matcher(response.toString()); 
     String[] person = null; 
     if (matcher.find()) 
     { 
      String p =matcher.group(0).substring(7, matcher.group(0).length()-3); 
      person = p.split("\\\\n"); 
     } 
     try { 
      String [] pp= 
       { 
        person[0 ], 
        person[1 ].split(":")[1].substring(1), 
        person[2 ].split(":")[1].substring(1), 
        person[10].split(":")[1].substring(1), 
        person[4 ].split(":")[1].substring(1), 
        person[5 ].split(":")[1].substring(1), 
        person[6 ].split(":")[1].substring(1), 
        person[7 ].split(":")[1].substring(1), 

       }; 

      CvsWrite(pp); 
     } catch (Exception e) { 

     } 
    } 
    public static void CvsWrite(String[] args) throws IOException { 
     List<String> pers = new ArrayList<>(); 
     for (String string : args) pers.add(string); 
     String clct1 = pers.stream().collect(Collectors.joining(",")) + "\r\n"; 
     File f = new File(path); 
     if (!f.exists()) 
      try { 
       f.createNewFile(); 
       List<String> test = new ArrayList<>(); 
       test.add("الملاحظة"); 
       test.add("رقم التسجيل"); 
       test.add("الشعبة"); 
       test.add("المعدل"); 
       test.add("اللقب"); 
       test.add("الاسم"); 
       test.add("مكان الميلاد"); 
       test.add("تاريخ الميلاد"); 
       String clct2 = test.stream().collect(Collectors.joining(","))+ "\r\n\r\n"; 
       Files.write(Paths.get(path),clct2.getBytes(), StandardOpenOption.APPEND); 

     } catch (IOException e) {} 


     Files.write(Paths.get(path),clct1.getBytes(), StandardOpenOption.APPEND); 
    } 

} 

Ausgeführt von Eclipse, ist die Ausgabedatei perfekt mit UTF-8-Codierung.

Aus exportierten JAR-Dateien wird ein Teil der Ausgabedatei in ANSI-Codierung ausgegeben. Nun wäre das kein Problem sein, wenn ich nur diese Worte ich schreibe, aber der Code schreibt andere Inhalte in Arabisch, und der Ausgang sein wie

Ausgabedatei mit Notepad ++ in ANSI http://i.stack.imgur.com/6RGEj.png in UTF- eröffnet 8 http://i.stack.imgur.com/Li0qf.png

wie ich bereits erwähnt dieses Problem nicht aufgetreten ist, wenn sie von eclipse läuft

+0

Ich habe die Formatierung ein wenig aufgeräumt, aber ich glaube, Ihre Beispielausgabe ist falsch herum - Sie haben angegeben, dass die * korrekte * Ausgabe "in ANSI" ist und die fehlerhafte Ausgabe "in UTF-8" ist. Ich schlage vor, dass Sie Ihre Frage bearbeiten, um dies umzukehren, wenn Sie es tatsächlich andersherum meinten. –

+0

Nein, das Beispiel ist eine Ausgabe mit zwei Zeilen, erste Zeile ist in ANSI, die zweite ist in UTF-8 – Bil

+0

Nun, das ist * nicht * die Ausgabe von dem Code, den Sie bereitgestellt haben, und es würde keinen Sinn ergeben rund, da keine mir bekannte ANSI-Codierung tatsächlich mit Arabisch umgehen kann. ("ANSI" ist keine einzige feste Kodierung. Es ist eine ganze Reihe von ihnen.) Es würde wirklich helfen, wenn Sie eine [mcve] mit einer Beispielausgabe anstelle eines * Teils * Ihres Codes bereitstellen würden. –

Antwort

2

Nun, die genau wie klingt sind Sie verschiedene Standard-Kodierungen bekommen, wenn auf verschiedene Weise ausgeführt wird - die etwas zu erwarten.

einfach die Codierung angeben, wenn Sie den Text, um binäre konvertieren:

byte[] bytes = col.getBytes(StandardCharsets.UTF_8); 
Files.write(Paths.get(path), bytes, StandardOpenOption.Append); 

(ich vorgeschlagen hätte Files.write und vorbei direkt im Text verwenden, aber das wird die Plattform-Standardzeilenumbruch verwenden, das würde sein ein anderes Thema ...)

Sie haben das gleiche Problem bekommen, wenn ein InputStreamReader erstellen:

in = new BufferedReader(new InputStreamReader(con.getInputStream())); 

dass Esel ist Ändern, dass die Daten in der Plattform-Standardcodierung sind. Niemals davon ausgehen, dass. Sie sollten herausfinden, was die tatsächlichen Codierung der Daten ist, und verwenden Sie diese zu lesen. Entscheiden Sie dann (als separate Angelegenheit), in welche Codierung Sie schreiben möchten.

+0

Entschuldigung, aber es hat es nicht gelöst. – Bil

+2

@Bil: Hoffentlich, wenn du die Frage klarer gestellt hast, können wir es klären. Aber Sie sollten die Kodierung, die Sie wollen, unbedingt einmal angeben * wenn Sie Text in Binärdaten umwandeln. –

+0

Vielen Dank, Sir, das werde ich auf jeden Fall berücksichtigen. – Bil

1

Verwendet wurde String.getBytes(), die die Standard-Betriebssystemcodierung des aktuellen Computers verwendet. Das ist nicht tragbar. Geben Sie die Codierung an.

Da der vorhandene alte Inhalt ANSI war, fahren Sie mit ANSI fort.

Files.write(Paths.get(path), clct2.getBytes("Windows-1256"), StandardOpenOption.APPEND); 

und die Datei mit ANSI lesen:

String s = new String(bytes, "Windows-1256"); 
+0

Wenn * überhaupt möglich *, wäre es besser UTF-8 konsequent zu verwenden. –

+0

@JonSkeet Total stimmen zu (gab +1), aber wenn Sie ein Lemming sein. –

+1

Die erste Zeile muss korrekt angezeigt werden und das war mit "ANSI". Leider ist ANSI ein Catch-All für jede Kodierung. Im UTF-8-Bild konnte man die Hex-Codes der arabischen Buchstaben lesen. Vielleicht hilft das, die richtige Kodierung zu finden. Cp708, Cp720, Cp864, Cp10004, Cp20420 schrecklich. Vielleicht alte Dateien zum universellen UTF-8 "korrigieren" –

1

Verwendung der Standard-Betriebssystem-Codierung für die erste und zweite Datei-Schreiboperation oder die gleiche Codierung für beiden Angeben angetroffen das gleiche Problem, das ist Kodierung Konflikt. Die Lösung ist:, um die Kodierung für die erste Dateischreiboperation an UTF-8 anzugeben.

. 
. 
String clct2 = test.stream().collect(Collectors.joining(","))+ "\r\n\r\n"; 
Files.write(Paths.get(path),clct2.getBytes("UTF-8"), StandardOpenOption.APPEND); 
     } catch (IOException e) {} 
Files.write(Paths.get(path),clct1.getBytes(), StandardOpenOption.APPEND); 
. 
. 

Dies ist sicherlich eine dumme Lösung, da der Bug über Portabilität und Standard-OS-Codierung ist, aber es funktionierte :)