Как программа запускается после выхода из main ()? - PullRequest
2 голосов
/ 14 февраля 2012

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

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

Вот код:

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;
}

}

Ответы [ 3 ]

3 голосов
/ 14 февраля 2012

Виртуальная машина завершает все действия и завершает работу после того, как последний поток , не являющийся демоном («Пользовательский поток»), завершил (или вызвал какой-либо поток System.exit()). Этот последний пользовательский поток не обязательно должен быть основным потоком.

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

1 голос
/ 14 февраля 2012

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

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

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

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

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

0 голосов
/ 14 февраля 2012

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

...