2012-02-14 1 views
2

Я написал программу, которая использует поток twitter для записи твитов в режиме реального времени до File через BufferedWriter. Но bufferedWriter не пишет текст, пока я не вызову метод close() в конце основной функции.Как запускается программа после выхода main()?

Теперь, когда я запускаю программу, файл сначала закрывается, а затем начинают появляться твиты. Как эта вещь работает после основных выходов ???

Вот код:

package analytics; 


import twitter4j.*; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.Arrays; 

общественного Trial_Filters конечного класс {

static String Tweet; 
static FileWriter output; 
static BufferedWriter writer; 



public static void main(String[] args) throws TwitterException,IOException { 



    if (args.length < 1) { 
     System.out.println("Usage: java twitter4j.examples.PrintFilterStream [follow(comma separated numerical user ids)] [track(comma separated filter terms)]"); 
     System.exit(-1); 
    } 


    output= new FileWriter("Log.txt"); 
    writer=new BufferedWriter(output); 




    StatusListener listener = new StatusListener() { 
     public void onStatus(Status status) { 
      StringBuilder temp; 


      //System.out.print("<sta>"); // Start Status -- helps for parsing two lines tweet;<sta> and </sta> used as tweet delimiters 
      temp=new StringBuilder("<sta>"); 

      if(status.isRetweet()) 
       temp.append("%");//System.out.print("%"); // easier to identify ReTweets 

      //System.out.println("@" + status.getUser().getScreenName() + " - " + status.getText()); 
      temp.append("@" + status.getUser().getScreenName() + " - " + status.getText()); 

      //System.out.print("</sta>"); //End Status 
      temp.append("</sta>"); 

      Tweet=temp.toString(); 

      this.add_to_Log(); 

     } 


     private void add_to_Log(){ 
      // TODO Auto-generated method stub 
      try{ 
      output= new FileWriter("Log.txt"); 
      writer=new BufferedWriter(output); 

      writer.write(Tweet); 
      System.out.println(Tweet); 
      } 
      catch(Exception e) 
      { 
       System.out.println(e); 
      } 

     } 


     public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { 
      System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId()); 
     } 

     public void onTrackLimitationNotice(int numberOfLimitedStatuses) { 
      System.out.println("Got track limitation notice:" + numberOfLimitedStatuses); 
     } 

     public void onScrubGeo(long userId, long upToStatusId) { 
      System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId); 
     } 

     public void onException(Exception ex) { 
      ex.printStackTrace(); 
     } 
    }; 

    TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); 
    twitterStream.addListener(listener); 
    ArrayList<Long> follow = new ArrayList<Long>(); 
    ArrayList<String> track = new ArrayList<String>(); 
    for (String arg : args) { 
     if (isNumericalArgument(arg)) { 
      for (String id : arg.split(",")) { 
       follow.add(Long.parseLong(id)); 
      } 
     } else { 
      track.addAll(Arrays.asList(arg.split(","))); 
     } 
    } 
    long[] followArray = new long[follow.size()]; 
    for (int i = 0; i < follow.size(); i++) { 
     followArray[i] = follow.get(i); 
    } 
    String[] trackArray = track.toArray(new String[track.size()]); 

    // filter() method internally creates a thread which manipulates TwitterStream and calls these adequate listener methods continuously. 
    twitterStream.filter(new FilterQuery(0, followArray, trackArray)); 


    try{ 
     System.out.println("bye"); 
     writer.close(); 
     } 
     catch(Exception e) 
     { 
      System.out.println(e); 
     } 


    } 


private static boolean isNumericalArgument(String argument) { 
    String args[] = argument.split(","); 
    boolean isNumericalArgument = true; 
    for (String arg : args) { 
     try { 
      Integer.parseInt(arg); 
     } catch (NumberFormatException nfe) { 
      isNumericalArgument = false; 
      break; 
     } 
    } 
    return isNumericalArgument; 
} 

}

+1

Pls предоставляет образец кода. – takacsot

+0

Время выполнения отключается после возврата функции 'main()'. Предположительно, это то, что вызывает поведение. Но трудно сказать больше, чем без кода вообще. –

+3

Вы можете заставить BufferedWriter написать свой вывод с явным вызовом 'flush'. Когда это происходит, содержимое буфера, которое он записывает в базовый выходной поток и буфер, опустошается. –

ответ

1

Объект TwitterStream запустит поток, и этот поток перезвонит на StatusListener. Программа будет работать до тех пор, пока не будет запущен поток, даже если основной поток, кажется, завершился, он ждет, пока все остальные потоки остановятся, до остановки основного потока, и программа завершит работу.

Не имеет значения, закрываете ли вы автора или нет в конце основного. Ссылка на автора будет переписана при каждом вызове add_to_log. Это означает, что при каждом новом статусе создается новый экземпляр, записывается сообщение в буферизатор.

Следующие две строки в начале кода не имеют значения:

output= new FileWriter("Log.txt"); 
writer=new BufferedWriter(output); 

Однако было бы лучше назвать заподлицо() или закрыть() в add_to_log, чтобы убедиться, что все будет записано на диск.

3

Виртуальная машина расторгает все действия и выход после последнего non-daemon thread ("User Thread") has terminated (или какой-то поток вызова System.exit()). Этот последний пользовательский поток не обязательно должен быть потоком main.

твиты (пакеты) отправляются в локальный сокет, и сокет привязывается только до тех пор, пока виртуальная машина работает и работает (если розетка не была закрыта вручную). Таким образом, канал может быть отправлен, но компьютер не принимает данные, а источник чириканья получит ошибки.

+1

Я исправил это, чтобы сказать, что main заканчивается, когда последний не-демона заканчивается, чтобы быть правильным. – Voo

+0

Это немного запутаннее, чем раньше. Вы добавили в обсуждение темы, отличные от Java, не так ли? Процессы, запускаемые приложением Java, но полностью отключенные от JVM? Затем я добавлю ваш действительный комментарий, говоря о «Java Threads». –

+0

Нет, он прав, и ваш ответ должен указывать нить-демона. –

0

Когда вы закрываете программу с активированным буферизированным Writer, система запускает буферизованный писатель, чтобы очистить его вывод до любой конечной точки, к которой он подключен, будь то файл или stdout. Со временем, что может произойти, это то, что документы поступают в сокет и помещаются в буферизованный сценарий, но ваш писатель просто сохраняет их, потому что вы не вызывали flush() из кода или порога записи для выполнения дамп не пересек. Когда вы звоните близко, под капотом он вызывает флеш и принудительно выдает выходной сигнал - даже если программа «закрыта».