2017-07-10 1 views
0

Ich verwende eine Pipe-getrennte .txt Datei mit Linienflügen. Ich muss jede Zeile in seine drei separate Teile brechen, scheduledTime, eventType und flightID ein Beispiel Flug innerhalb der .txt Datei würde wie folgt aussehen:Scanner und Pipe getrennte Datei Java

12: 00 | ANREISE | A001

habe ich es Arbeit für eine Einzelflug, aber wenn ich hinzufügen mehr bekomme ich diese Fehler

Voll Trace:

java.time.format.DateTimeParseException: Text 'ARRIVAL' could not be parsed at index 0 
at java.time.format.DateTimeFormatter.parseResolved0(Unknown Source) 
at java.time.format.DateTimeFormatter.parse(Unknown Source) 
at java.time.LocalTime.parse(Unknown Source) 
at java.time.LocalTime.parse(Unknown Source) 
at edu.metrostate.ics240.p4.gaw886.sim.AirportSimulator.processEventFile(AirportSimulator.java:49) 
at edu.metrostate.ics240.p4.gaw886.sim.tests.AirportSimTests.testScenarioOne(AirportSimTests.java:22) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

jetzt verstehe ich, was hier geschieht, wenn ich mehr als einen Flug haben, ist es s Sie kippen über das Element "GeplantesTime" in der zweiten Zeile und versuchen stattdessen, den Ereignistyp zu analysieren. Ich kann nicht herausfinden, wie ich das beheben kann. Hier sind meine Methoden:

public static final double DEPARTURE_PROB = 0.20; 
public static final double ARRIVAL_PROB = 0.15; 
public static final int ARR_RESERVE_TIME = 2; 
public static final int DEP_RESERVE_TIME = 3; 
public static final int SIM_MINUTES = 60; 
public static final long SEED = 20170620001L; 
public static final Random RAND = new Random(SEED); 
public static final String DELIM = "\\|"; 

public static void genEventFile(String fileName, double arrivalProbability, double departureProbability, 
     int minutes) { 
    int arrFlightId = 1; 
    int depFlightId = 1; 
    try (PrintWriter simFile = new PrintWriter(fileName);) { 
     LocalTime time = LocalTime.parse("00:00"); 

     for (int i = 0; i < minutes; i++) { 
      if (RAND.nextDouble() <= arrivalProbability) { 
       simFile.printf("%s|%s|%s\n", time.plusMinutes(i), Event.EventType.ARRIVAL, 
         String.format("A%03d", arrFlightId++)); 
      } 
      if (RAND.nextDouble() <= departureProbability) { 
       simFile.printf("%s|%s|%s\n", time.plusMinutes(i), Event.EventType.DEPARTURE, 
         String.format("D%03d", depFlightId++)); 
      } 
     } 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
} 

und die Methode der Ereignisdatei zu verarbeiten:

Methode, um die Ereignisdatei zu erstellen

public void processEventFile(String filename) { 
    LocalTime scheduledTime = null; 
    EventType eventType; 
    String flightID; 
    try (Scanner scanner = new Scanner(new File(filename)).useDelimiter(DELIM);) { 
     while (scanner.hasNext()) { 
      scheduledTime = LocalTime.parse(scanner.next()); 
      eventType = EventType.valueOf(scanner.next()); 
      flightID = scanner.next(); 
      flight = new Flight(scheduledTime, eventType, flightID); 
      flightQueue.add(flight); 
     } 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
} 

Also meine Frage ist, wie kann ich den Scanner bewegen zur nächsten Zeile nach dem Lesen der flightId und nicht denken, dass die flightId der Zeile 1 und scheduledTime der Zeile zwei auf der gleichen Linie sind? Flugdaten

Probe:

00:02|DEPARTURE|D001 
00:03|ARRIVAL|A001 
00:03|DEPARTURE|D002 
00:04|DEPARTURE|D003 
00:06|DEPARTURE|D004 
00:09|DEPARTURE|D005 
00:12|ARRIVAL|A002 
00:14|ARRIVAL|A003 
00:16|DEPARTURE|D006 
00:18|ARRIVAL|A004 
00:21|DEPARTURE|D007 
00:22|ARRIVAL|A005 
00:24|DEPARTURE|D008 
00:28|ARRIVAL|A006 
00:28|DEPARTURE|D009 
00:30|ARRIVAL|A007 
00:41|ARRIVAL|A008 
00:44|DEPARTURE|D010 
00:47|DEPARTURE|D011 
00:48|DEPARTURE|D012 
00:53|DEPARTURE|D013 
00:54|ARRIVAL|A009 
00:54|DEPARTURE|D014 
00:56|DEPARTURE|D015 
00:57|DEPARTURE|D016 
+1

Könnten Sie einen BufferedReader verwenden? Dann könntest du eine Zeile nach der anderen lesen und String.split (regex) verwenden, um jede Zeile in ihre Komponenten aufzuteilen –

+1

Kannst du eine Beispieltxt-Datei mit Flug-ID und Zeit posten –

Antwort

3

Das Scanner Objekt nur Parsen der Datei auf der Grundlage Ihrer DELIM Variable |. Die Datei wird auch nicht durch das neue Zeilenzeichen getrennt.

Sie können ein BufferedReader Objekt verwenden, um die Datei zeilenweise zu lesen und den Text später zu teilen. So etwas wie dieses:

public void processEventFile(String fileName) { 
    String line; 
    String[] split; 
    BufferedReader reader = null; 
    try { 
      reader = new BufferedReader(new FileReader(fileName)); 
      while((line = reader.readLine()) != null) { 
       split = line.split("\\|"); 
       flightQueue.add(new Flight(split[0], split[1], split[2])); 
      } 
    } catch(IOException e) { 
      e.printStackTrace(); 
    } finally { 
      if(reader != null) { 
       try { 
        reader.close(); 
       } catch(IOException e) { 
        e.printStackTrace(); 
       } 
      } 
    } 
} 
+0

Ehrfürchtig, das hat es gefixt. –

0

Sie können Ihr Begrenzungszeichen ändern, um OR-Bedingung zu verwenden.

public static final String DELIM = "[\\||\n]+"; 
0

Sie können java.util.Scanner verwenden, um Datei zeilenweise zu lesen. Im Beispiel verwende ich try-with-resources Block, um sicherzustellen, dass Scanner geschlossen ist. Methode forEachRemaining gibt nächste Zeile der Eingabedatei zurück:

public static void main(String[] args) throws ParseException { 
     try (Scanner sc = new Scanner(NewMain.class.getResourceAsStream("airport.txt"))) { 
      sc.forEachRemaining(s -> { 
       System.out.println(s.length() + " " + s); 
      }); 
     } 
    }