简体   繁体   中英

Why am I receiving a java.io.IOException in this loop?

I have written the following block of code which picks up a plaintext file, and if the current modified date on the file is greater than the last iteration of the loop, parse the file into an HTML version and upload it to an ftp server. I believe the issue is something to do with the Writer, but I am not understanding what is happening here. The first iteration of the loop seems to execute fine, and then it sleeps for 5 minutes and throws the following error:

java.io.IOException: Stream closed
at java.io.BufferedWriter.ensureOpen(BufferedWriter.java:116)
at java.io.BufferedWriter.write(BufferedWriter.java:221)
at java.io.Writer.write(Writer.java:157)
at java.io.Writer.append(Writer.java:227)
at PrintOutConvosFtp3.main(PrintOutConvosFtp3.java:130)

Here is the code which is throwing the error:

import java.io.*;
import java.util.*;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import java.sql.Timestamp;

public class PrintOutConvosFtp3
{
public static void main(String[] args) throws IOException, InterruptedException
    {
    boolean infiniteLoop = true;
    long currentLoopModified = 0;
    long lastLoopModified = 0;

    while (infiniteLoop)
    {
    currentLoopModified = new File("C:/Documents and Settings/Cuckoo/Desktop/Syss-convos.LOG").lastModified();
    if (currentLoopModified > lastLoopModified)
    {

    //Read in the conversation log
BufferedReader reader = new BufferedReader(new FileReader("C:/Documents and Settings/Cuckoo/Desktop/Syss-convos.LOG"));
FileWriter output = new FileWriter("C:/Documents and Settings/Cuckoo/Desktop/Conversations.html");
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = reader.readLine()) != null)
    //Remove some unnecessary clutter from the log
 {
 if (!(line.contains("just hung up!!!") || line.contains("just left the Realm.")
        || line.contains("Hurry, I've many esoteric secrets to divulge, and welcome to BaDbOy's realm.")
        || line.contains("For custom MegaMud paths and additional information, check out the website:")
        || line.contains("Syss gossips: Discuss new ideas/issues & see the most up to date information on Facebook!")
        || line.contains("Syss gossips: http://www.facebook.com/groups/EsotericEdits/")
        || line.contains("Syss gossips: MME Dats, Megamud path files and quest walkthroughs are available at my site")
        || line.contains("Syss gossips: www.esoteric-edits.fhero.net")
        || line.contains("telepaths: @")
        || line.contains("I'm a bot.  Try telepathing me with @commands.")
        || line.contains("Syss gossips: Remember, you can telepath me @commands for useful things like adding lives.")
        || line.contains("Syss gossips: Bring a friend, help keep mud alive!")
        || line.contains("You say \"http://esoteric-edits.fhero.net/\"")
        || line.contains("For a list of available commands, you can telepath me with @commands.")))
 {
 //Make the dates american style
     String day = line.substring(0,2);
     String month = line.substring(3,5);
lines.add(month + "/" + day + line.substring(5));
}


 }
//initialize the output file with HTML header
output.write("<html>");
output.write(System.getProperty("line.separator") + "\t<head>");
output.write(System.getProperty("line.separator") + "\t\t<link type=\"text/css\" rel=\"stylesheet\" href=\"stylesheet.css\"/>");
output.write(System.getProperty("line.separator") + "\t\t<title>Esoteric Edits BBS - Conversation Log</title>");
output.write(System.getProperty("line.separator") + "\t</head>");
output.write(System.getProperty("line.separator") + "\t<body>"+ System.getProperty("line.separator") + System.getProperty("line.separator"));
output.write(System.getProperty("line.separator") + "<div id='cssmenu'>");
output.write(System.getProperty("line.separator") + "\t\t<center><img src=\"logo_10_2.png\">");
output.write(System.getProperty("line.separator") + "<ul>");
output.write(System.getProperty("line.separator") + "\t<li> <a href='index.html'><span>Home</span></a></li>");
output.write(System.getProperty("line.separator") + "\t<li> <a href='downloads.html'><span>Downloads</span></a></li>");
output.write(System.getProperty("line.separator") + "\t<li> <a href='Quests.html'><span>Quest Walkthroughs</span></a></li>");
output.write(System.getProperty("line.separator") + "\t<li> <a href='https://www.facebook.com/groups/EsotericEdits/'><span>Facebook</span></a></li>");
output.write(System.getProperty("line.separator") + "\t<li> <a href='captures.html'><span>Captures</span></a></li>");
output.write(System.getProperty("line.separator") + "\t<li class='last'> <a href='FAQs.html'><span>FAQs</span></a></li>");
output.write(System.getProperty("line.separator") + "</ul></center>");
output.write(System.getProperty("line.separator") + "</div><div id='mainpage'>");
output.write(System.getProperty("line.separator") + "<center><img src=\"divider.png\"></center>");

//write out a new file with HTML coloration
for (ListIterator<String> iter = lines.listIterator(); iter.hasNext(); ) 
{
    String currentline = iter.next();
    output.write("<b>"); //make everything bold
    if (currentline.contains("gangpaths: "))
{
output.write(System.getProperty("line.separator") + "<font color=\"#808000\">" + currentline + "<br></font>");
}
    else if (currentline.contains("gossips: ") || currentline.contains("auctions: "))
{
output.write(System.getProperty("line.separator") + "<font color=\"#FF00FF\">" + currentline + "<br></font>");
}
else if (currentline.contains("Broadcast from "))
{
output.write(System.getProperty("line.separator") + "<font color=\"yellow\">" + currentline + "<br></font>");
}
else if (currentline.contains("says \"") || currentline.contains("greets you.") || currentline.contains("bows deeply.")
             || currentline.contains("breaks into a wide grin.") || currentline.contains("You say \"") 
             || currentline.contains("nods affirmatively.") || currentline.contains("grin slyly"))
{
output.write(System.getProperty("line.separator") + "<font color=\"green\">" + currentline + "<br></font>");
}
else
{
output.write(System.getProperty("line.separator") + currentline + "<br>");
}
}
//finalize the HTML footer
output.write(System.getProperty("line.separator") + "</b>");
output.write(System.getProperty("line.separator") + "</div>");
output.write(System.getProperty("line.separator") + "</body>");
output.write(System.getProperty("line.separator") + "\t</html>");
output.close(); //file is finalized locally



//define variables for FTP process
String server = "servername";
int port = 21;
String user = "fake";
String pass = "password";

//begin FTP process to web server
FTPClient ftpClient = new FTPClient();
FileInputStream fis = null;
try {

    File localFile = new File("C:/Documents and Settings/Cuckoo/Desktop/Conversations.html");
    ftpClient.connect(server, port);
    ftpClient.login(user, pass);
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    fis = new FileInputStream(localFile);
    String remoteFile = "/public_html/Conversations.html";
    ftpClient.storeFile(remoteFile, fis);
    java.util.Date currentDate = new java.util.Date();
    Timestamp ftpTimestamp = new Timestamp(currentDate.getTime());
    //Create writer file to log iterations of the loop as successful or skipped.
    Writer writer = new BufferedWriter(new FileWriter("C:/Documents and Settings/Cuckoo/Desktop/Convo-Upload.log", true));
    writer.append("Successfully uploaded file as of " + ftpTimestamp.toString() + System.getProperty("line.separator"));
    writer.close(); //close the iteration logger
    ftpClient.logout();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (fis != null) {
            fis.close();
        }
        ftpClient.disconnect();
    } catch (IOException e) {
        e.printStackTrace();
        }
    }


lastLoopModified = currentLoopModified; //set the timestamp for the lastmodified on the file being read in
Thread.sleep(300000); //5 minutes
}
    else
    {
        java.util.Date currDate = new java.util.Date();
        Timestamp currTimestamp = new Timestamp(currDate.getTime());
        //Create writer file to log iterations of the loop as successful or skipped.
        Writer writer = new BufferedWriter(new FileWriter("C:/Documents and Settings/Cuckoo/Desktop/Convo-Upload.log", true));
        writer.append("Did not detect any new content in file.  Did not upload as of " + currTimestamp.toString() + System.getProperty("line.separator"));
        writer.close(); //close the iteration logger
    }
}

}
}

I am thinking this has to do with the writer being closed out, but I have tried moving it around, leaving it open until the endless loop is finished (which is never), etc and I am still getting strange behavior. Have I done something wrong?

I ran the code on my machine and it ran fine - I commented out only the code related to the FTP transfer as I am unable to do that here. My machine is fairly new and fast, so I suspect there may be a timing issue.

The line of code where the stack trace points to could be having issue with the Thread.Sleep(nnn). If the Sleep blocks the Thread before the Writers have finished their tasks, then this could cause your problem.

If this is the issue, rather than doing all this work on the main Thread, it would be better to spawn a new thread to perform the Execution and place all the code (except I think keeping the Thread.sleep in the main thread only) within here. By using a separate Thread to perform the writing tasks, it will give the Writers enough time to complete their tasks, without being held up by the Sleep .

Also, In your current implementation, if something hasn't changed the Sleep is not invoked as it is embedded only within the "changed" part of the loop, therefore it heads straight back into checking the time change again, without any delaying at all.

If you examine the code closely, you will notice the Thread.sleep() was only being executed when the file had been updated since the last iteration. Whenever this was not true, i think it was being thrown into a wild endless loop of "write not updated timestamp" etc... endlessly. I moved the Thread.sleep() statement outside of both the if and else statements right before the end of the while } bracket and it now seems to execute wonderfully. Thank you guys for all your help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM