mboost-dp1

Java, Windows og ISO-8859-1


Gå til bund
Gravatar #1 - arntc
30. jul. 2009 10:51
Hej Gutter

Nu er jeg snart desperat. Jeg har udviklet en applikation for en virksomhed som anvender et forældet regnskabsprogram. De får et output i en fil som skal formateres til at imødegå kravene fra PBS.
Til det har jeg lavet en java applikation, som tager den gamle fil, og ved hjælp af en Stringbuilder retter den til med mellemrum og linieskift.

Problemet kommer her: Jeg kan let og elegant konvertere de PBS filer på min maskine (Windows 7). De får ikke andet end volapyk på deres.

Jeg mistænker selv at der er et problem med character encoding, som jeg dog har forsøgt at løse uden held.

Jeg har forsøgt at bede mit program om at oprette den nye fil med ISO-8859-1 (eksempel her):

File nyPBSFil = new File("NyPBS.PBS");
try{

// Create file
FileOutputStream fos = new FileOutputStream(nyPBSFil);
out = new OutputStreamWriter(fos, "ISO-8859-1");
out.write(finalLine);
out.close();
}
catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}

Uden større held :(

Så har jeg forsøgt med hjælp af en UTF til ASCII konverter:

http://tripoverit.blogspot.com/2007/04/javas-utf-8...

Også uden held.

Min applikation er på 500 linier, så jeg har svært ved at poste ret meget kode her, men her er et eksempel på hvordan jeg tilretter filen

content.append(text.substring(0, 9) + "1194" + text.substring(13, 30) + " " + text.substring(30,36)+" "); //Første header linie
content.append(System.getProperty("line.separator"));

Har i nogen ideér?
Gravatar #2 - arntc
30. jul. 2009 11:47
Her er noget mere kode, det kan være det opklarer problemet:

(Class PBSConverterApp)


public void converts(File pbsFile) throws IOException {
text = "";
StringBuilder content = new StringBuilder();

Scanner s = null;
try {
s = new Scanner(new BufferedReader(new FileReader(pbsFile)));

while (s.hasNext()) {
text = text + s.next();
}
} finally {
if (s != null) {
s.close();
}
}
//Startlinie 1
content.append(text.substring(0, 9) + "1194" + text.substring(13, 30) + " " + text.substring(30,36)+" "); //Første header linie
content.append(System.getProperty("line.separator"));
text = text.substring(36, text.length()); //Fjern første linie

//Startlinie 2
content.append(text.substring(0, 14) + "112" + " " +text.substring(17, 22)+" "+text.substring(23,28)+"68800002748092"+" ");
content.append(System.getProperty("line.separator"));
text = text.substring(42, text.length()); //Fjern anden linie

//Endline 1 og 2
endLine = text.substring(text.length()-201,text.length());
String endLine1 = endLine.substring(0, 14) + "112" + endLine.substring(17,24) + "00" + endLine.substring(24,25) + " " + endLine.substring(25,63) + " " + endLine.substring(63, 73)+" ";
String endLine2 = endLine.substring(73, endLine.length());
text = text.substring(0, text.length()-201);

endLine2 = endLine2.substring(0,9) + "1194" + endLine2.substring(13,endLine2.length());

int numRecords = Integer.valueOf(endLine2.substring(40,42 )).intValue();

int i = 0;
while (i < numRecords) {
content.append(text.substring(0,69) + " " + text.substring(73,75)+" ");
content.append(System.getProperty("line.separator"));
text = text.substring(75, text.length());
i++;
}
content.append(endLine1);
content.append(System.getProperty("line.separator"));
content.append(endLine2);




finalLine = content.toString();
//try {
//finalLine = new String((new UnicodeUtil().convert(finalLine.getBytes(), "ASCII")));
//}
//catch (Exception e)
//{}
// Create the encoder and decoder for ISO-8859-1
Charset charset = Charset.forName("ISO-8859-1");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();

try {
// Convert a string to ISO-LATIN-1 bytes in a ByteBuffer
// The new ByteBuffer is ready to be read.
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(finalLine));

// Convert ISO-LATIN-1 bytes in a ByteBuffer to a character ByteBuffer and then to a string.
// The new ByteBuffer is ready to be read.
CharBuffer cbuf = decoder.decode(bbuf);
finalLine = cbuf.toString();
}
catch (CharacterCodingException e) {
}


}

public File createFile() {
File nyPBSFil = new File("NyPBS.PBS");
try{

// Create file
FileOutputStream fos = new FileOutputStream(nyPBSFil);
out = new OutputStreamWriter(fos, "ISO-8859-1");
out.write(finalLine);
out.close();
}
catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
return nyPBSFil;


}



Gravatar #3 - JensOle
30. jul. 2009 12:23
Hvad sker der med :

System.getProperty(";line.separator")

skulle det ikke bare være

System.getProperty("line.separator")

jeg ved ikke om det gør en forskel.
eller hvis filen skal være i et "låst format" så kunne du nok bare bruge "/r/n"
Gravatar #4 - JensOle
30. jul. 2009 12:27
og kunne du ikke droppe :


Charset charset = Charset.forName("ISO-8859-1");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();

try {
// Convert a string to ISO-LATIN-1 bytes in a ByteBuffer
// The new ByteBuffer is ready to be read.
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(finalLine));

// Convert ISO-LATIN-1 bytes in a ByteBuffer to a character ByteBuffer and then to a string.
// The new ByteBuffer is ready to be read.
CharBuffer cbuf = decoder.decode(bbuf);
finalLine = cbuf.toString();
}
catch (CharacterCodingException e) {
}
Gravatar #5 - JensOle
30. jul. 2009 12:30
og så husk at flushe inden close

out.write(finalLine);
out.flush();
out.close();
Gravatar #6 - KaW
30. jul. 2009 12:31
Hej,
Har ikke et praktisk forslag til din kode, men et forslag til din kode. I stedet for at rette i blinde, burde du kigge på noget VMWare så du kan emulere din kundes setup i Windows XP.

Det gør det meget nemmere for dig i din udviklingsproces.

Håber du finder ud af noget :)
Gravatar #7 - JensOle
30. jul. 2009 12:40
Nu ved jeg ikke hvordan du kører det men prøv lige at tilføje :
		 javax.swing.JOptionPane.showMessageDialog(null, finalLine , "Output", JOptionPane.PLAIN_MESSAGE );

som første linje i din createFile() metode.
Det kunne være det gav nogle ideer.

Gravatar #8 - arne_v
30. jul. 2009 13:26
Hvilket system er det de får volapyk på og hvilket karakter sæt bruger de ?

Hvis de bruger EBCDIC skal de ihvertfald ikke angive ISO-8859-1 i output.

Mit råd er:
- find ud af hvad karakter sæt de bruger på det system
- angive det i både read og write (du angiver kun ISO-8850-1 for write ikke for read !)

De skal have et meget specielt setup for at det er nødvendigt med specielle konverterings klasser/metoder.
Gravatar #9 - arntc
30. jul. 2009 13:43
Tak for svarene.

#3 C/P fejl fra netbeans, heldigvis, ellers ville jeg rive mit hår ud.

#4 Det var egentlig hvad jeg troede var et fix til problemet.

#5 Tak, havde misset den

#6 Har overvejet det flere gange, men alligevel kommer du aldrig i nærheden af kundens setup, da opdateringer, programmer, registreringsindstillinger osv. aldrig bliver 100% nøjagtige.

#7 Prøver lige

#8 Windows XP Pro SP3 Dansk med default character set. Har sendt min applikation til min far som har samme setup på arbejdet og han har ingen problemer med konverteringen...

Gravatar #10 - arne_v
30. jul. 2009 13:48
#5 & 9

close flusher automatisk så en eksplicit flush er ikke nødvendig.

http://java.sun.com/javase/6/docs/api/java/io/Outp...
Gravatar #11 - arne_v
30. jul. 2009 13:49
#9

Windows XP bør selvfølgelig virke. Er deres kopi af input filen god?
Gravatar #12 - arntc
30. jul. 2009 15:34
#11 Ja, deres fil er helt fin. Har endda forsøgt at sende min fil med. Stadig uden held.

I kan prøve at se på følgende filer:

http://www.a-com.dk/PBS601.PBS - Originalen

http://www.a-com.dk/NyPBS.PBS - Sådan som den skal se ud.

http://www.a-com.dk/NyPBS_kunde.PBS - Sådan som den ser ud hos kunden.

Gravatar #13 - Windcape
30. jul. 2009 15:39
Jeg ser en forbandede masse whitespace (0x20), og at lineskift behandles forskelligt fra fil til fil.

Du bør nok splitte på \n, istedet for Line.Seperator, da du ellers for problemer i \r\n systemer.

Samtidig bør du nok også strippe filen for unødvendig whitespace, og eventuelle \r, da det afhænger af brugerens fremviser om det bliver vist korrekt.
Gravatar #14 - arntc
30. jul. 2009 15:49
#13

Ja, jeg har overvejen \n istedet. Problemet med whitespace er at de SKAL være der. Det er derfor jeg indlæser den originale fil med en Scanner, for lettere at kunne detektere de rette steder at lave whitespace.

Mit spørgsmål til din kommentar går så på, skal jeg i min min kildekode anvende " " som whitespace eller "0x20"?
Gravatar #15 - arntc
30. jul. 2009 15:55
#13

Det bliver helt hen i vejret med \n som linieskift...
Gravatar #16 - Windcape
30. jul. 2009 16:18
Hvis du splitter på CRLF istedet for kun LF, så får man problemer med filer fra unix, der ikke benytter Carriage Return.

Det giver kun mening at benytte Enviroment Line.Seperator når man gemmer.
Gravatar #17 - arntc
30. jul. 2009 20:51
#16

Filen kommer fra en Windows 98 maskine til en Xp maskine via en USB stick.

Jeg har testet programmet på 6 andre XP maskiner uden vrøvl, så på mandag tester jeg på flere af kundens maskiner for at se om det er en isoleret fejl/indstilling på bogholderens maskine.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login