main()退出后程序如何运行?
我编写了一个程序,它使用 Twitter 流通过 BufferedWriter
将推文实时写入 File
。 但 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;
public Final class 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;
}
}
I have written a program that uses the twitter stream to write tweets in Realtime to a File
via a BufferedWriter
.
But the bufferedWriter does not write the text until i call the close()
method at the end of the main function.
Now, when i run the program, the file is closed at first and then the tweets start coming. How does this thing work after main exits???
Here is the Code:
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;
public final class 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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
虚拟机终止所有活动并在最后一个 后退出非守护线程(“用户线程”)已终止(或某个线程调用了
System.exit()
)。最后一个用户线程不必是主线程。推文(数据包)被发送到本地套接字,并且只有当虚拟机启动并运行时才会绑定套接字(如果套接字尚未手动关闭)。因此,提要可能正在发送,但计算机不会接受数据,并且推文源将收到错误。
The virtual machine terminates all activity and exits after the last non-daemon thread ("User Thread") has terminated (or some thread invoked
System.exit()
). That last User thread doesn't have to be the main thread.The tweets (packets) are sent to a local socket and the socket is only bound as long as the virtual machine is up and running (in case the socket hasn't been closed manually). So the feed may be sending but the computer won't accept the data and the tweet source will receive errors.
TwitterStream 对象将启动一个线程,该线程将回调 StatusListener。程序会一直运行,直到有一个线程在运行,即使主线程看起来已经完成,它也会等待所有其他线程停止,然后主线程停止,程序退出。
是否在 main 结束时关闭 writer 并不重要。每次调用 add_to_log 时,写入器的引用都会被重写。这意味着在每个新状态上都会实例化一个新写入器,将消息写入缓冲写入器。
代码开头的以下两行是无关紧要的:
但是,最好在 add_to_log 中调用lush() 或 close() 以确保所有内容都写入磁盘。
The TwitterStream Object will start a thread, and that thread will call back on the StatusListener. The program will run until there is a thread running, even if the main thread seems to have finished, it waits for all other threads to stop, before the main thread stops, and the program exits.
It does not matter if you close the writer or not on the end of main. The reference of the writer will be rewritten on each call to add_to_log. That means on each new status a new writer gets instantiated, writes out the message into the bufferedwriter.
The following two lines at the beginning of the code are irrelevant:
However it would be better to call flush() or close() in add_to_log to make sure everything gets written to disk.
当您在激活 bufferedWriter 的情况下关闭程序时,系统会触发缓冲编写器将其输出刷新到它所连接的任何端点,无论是文件还是标准输出。随着时间的推移,可能发生的情况是,文档到达套接字并被放入 bufferedwriter 中,但您的编写器只是将它们存储起来,因为您没有从代码或编写器阈值中调用lush()来执行转储尚未被跨越。当您在后台调用 close 时,它会调用lush 并强制输出转储——即使程序已“关闭”。
When you close a program with a bufferedWriter activated, the system triggers the buffered writer to flush its output to whatever endpoint it's hooked up to, be it a file or stdout. Over time, what could be happening, is that documents are arriving on the socket and getting placed into the bufferedwriter, but your the writer just stores them up because you haven't called flush() from the code or the writer threshold for doing a dump hasn't been crossed. When you call close, under the hood, it calls flush and forces the output to dump--even if the program is "closed".