Geht dieser Code noch einfacher (try catch finally)

  • Themenstarter Themenstarter hüteüberhüte
  • Beginndatum Beginndatum
H

hüteüberhüte

Gast
Java:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    private static final Pattern[] pat = {
        Pattern.compile("<img src=\"(http://www.example.com/1)\" class=\"[^\"]+\" alt=\"[^\"]+\" />"),
        Pattern.compile("<img src=\"(http://www.example.com/2)\" class=\"[^\"]+\" alt=\"[^\"]+\" />"),
        Pattern.compile("<img src=\"(http://www.example.com/3)\" class=\"[^\"]+\" alt=\"[^\"]+\" />")};
    private static final int[] indexes = new int[pat.length];
    private static final SimpleDateFormat sdf =
            (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
    private static final String formatStr = "%d_%04d.jpg";
    private static final ByteBuffer byteBuffer = ByteBuffer.allocate(262144);

    public static void main(String[] args) throws InterruptedException {
        GregorianCalendar gc_to = new GregorianCalendar(
                Integer.parseInt(args[0]),
                Integer.parseInt(args[1]) - 1,
                Integer.parseInt(args[2]),
                Integer.parseInt(args[3]),
                Integer.parseInt(args[4]));
        System.out.println("gc_to = " + sdf.format(gc_to.getTime()));
        while (System.currentTimeMillis() <= gc_to.getTimeInMillis()) {
            BufferedReader br = null;
            try {
                br = new BufferedReader(new InputStreamReader(new URL("http://www.example.com/").openStream()));
                String s;
                while ((s = br.readLine()) != null) {
                    for (int i = 0; i < pat.length; i++) {
                        Matcher m = pat[i].matcher(s);
                        if (m.find()) {
                            System.out.println(sdf.format(new Date()) + " Speichere " + m.group(1) + " ...");
                            byteBuffer.clear();
                            BufferedInputStream bis = null;
                            try {
                                bis = new BufferedInputStream(new URL(m.group(1)).openStream());
                                int b;
                                while ((b = bis.read()) != -1) {
                                    byteBuffer.put((byte) b);
                                }
                            } finally {
                                if (bis != null) {
                                    try {
                                        bis.close();
                                    } catch (IOException ioe) {
                                        ioe.printStackTrace();
                                    }
                                }
                            }
                            if (new File(String.format(formatStr, i + 1, indexes[i] - 1)).length() == byteBuffer.position()) {
                                break;
                            }
                            BufferedOutputStream bos = null;
                            try {
                                bos = new BufferedOutputStream(new FileOutputStream(String.format(formatStr, i + 1, indexes[i]++)));
                                for (int j = 0; j < byteBuffer.position(); j++) {
                                    bos.write(byteBuffer.get(j));
                                }
                                bos.close();
                            } finally {
                                if (bos != null) {
                                    try {
                                        bos.close();
                                    } catch (IOException ioe) {
                                        ioe.printStackTrace();
                                    }
                                }
                            }
                            break;
                        } // if m find
                    } // for pat
                } // while br readLine
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }
            } // try catch finally
            Thread.sleep(75L * 1000L);
        } // while millis
    } // main
} // Main

Er funktioniert, aber das Problem ist, ich steige selbst langsam nicht mehr durch. Kann man die Anzahl der try s... verringern, aber dass die Semantik erhalten bleibt?

Danke fürs Durchlesen...

Grüße!
 
Mit Java 7 und try-with-ressources oder du schreibst dir halt ne kleine Hilfsmethode:

Java:
public void close (Closeable c) {
  if (c != null) {
    try {
      c.close();
    } catch (IOException ioe) {
      ioe.printStacktrace();
    }
  }
}
Die kannst du dann aufrufen und sparst dir die drei try-catch Blöcke.
 
Sieht halt auch insgesamt sehr unübersichtlich aus - Parsen, Matchen, Regex, Dateiverarbeitung... alles in der main zusammengewurstet... Was wird da gemacht? Ist das (wieder einmal) der (zum Scheiter verurteilte) Versuch, HTML-Inhalte durch RegEx abzugrasen? Falls ja: Vielleicht mal einen passenden Parser verwenden. Da war kürzlich auch http://www.java-forum.org/allgemeine-java-themen/142697-html-parsing-errors.html#post949727 , was in eine ähnliche Richtung gehen könnte...
 
wie gesagt, java7 ist schonmal ein schritt, ansonten code duplikationen auslagern, abstraktionen einfuehren, bessere Methodensplitten und und und
 
@Marco: Das parsen funktioniert hervorragend. Close habe ich ausgelagert. Für das andere muss ich mir viell. noch etwas überlegen, wie man etwas in Methoden auslagern könnte. Das Ding ist, das zeilenweise eingelesen werden soll und wenn ein bestimmter Ausdruck zutrifft, wieder etwas geladen werden soll
 
Das

Java:
GregorianCalendar gc_to = new GregorianCalendar(
                Integer.parseInt(args[0]),
                Integer.parseInt(args[1]) - 1,
                Integer.parseInt(args[2]),
                Integer.parseInt(args[3]),
                Integer.parseInt(args[4]));

knallt doch sofort, wenn auf der Kommandozeile keine Zahlen übergeben werden. Das wird doch gar nicht behandelt und sieht als RuntimeException nicht gut aus.
 
@Marco: Das parsen funktioniert hervorragend.

Wenn jemand den Quelltext ändert zu
<img src=... CLASS=... alt=... />
(Groß/Kleinschreibung) oder gar zu
<img src=... alt=... class=... />
(Attributreihenfolge vertauscht)
haut's ihn komplett raus. Vielleicht ist dir das egal, wenn es ein "one-shot-Utility" ist (ja, sowas macht jeder mal 😳 ) aber allgemein gilt: Man parst HTML einfach nicht mit RegEx :noe:
 
Das mit gc_to ist schon ok, und ist auch gewollt, dass das Programm dann gar nicht erst startet. Es ist nur für mich gedacht, und die "Ziel"-Seite ändert sich so schnell net.
Regex ist deshalb die beste Wahl - selbst mit einem HTML-Parser müsste auf veränderte Strukturen reagiert werden.
Danke aber für Vroschläge!
 

Zurück
Oben