Tomcat servlet无法读取文件

时间:2014-07-14 19:26:03

标签: java file tomcat servlets

我正在制作一个Java Web应用程序,它将在Tomcat下运行。代码将从文件(在服务器上)读取一个数字,进行一些处理,并将结果写回同一文件(覆盖旧内容,不附加它)并将其显示在用户的HTML页面中。

我正在使用这个单例(以避免可能的多线程问题)来读取和写入文件,以及返回数字。 servlet类调用此方法。

public class Singleton {

private static Singleton instance;
private ObjectOutputStream fileOut;
private ObjectInputStream fileIn;
private File file;
private static final String fileName = "/Users/Timmy/Desktop/IDFile.txt";
private static final int SCALE = 1000000;

public synchronized long getNewID() throws IOException{
    if(file == null){
        file = new File(fileName);
    }
    if(!file.exists()){
        file.createNewFile();
    }
    fileOut = new ObjectOutputStream(new FileOutputStream(file));   
    fileIn = new ObjectInputStream(new FileInputStream(file));

    long lastId;
    String idString;
    try{
        idString = fileIn.readUTF();
        lastId = Long.parseLong(idString);
    }catch(EOFException e){
        System.out.println("EOF EXCEPTION WHILE READING");
        e.printStackTrace();
        lastId = (long)(Math.random() * SCALE);
    }


    fileIn.close();
    fileIn = null;

    long nextId = lastId + ((long)(Math.random() * SCALE)) + 1;

    fileOut.writeChars(Long.toString(nextId) + "\n");
    fileOut.close();
    fileOut = null;

    return nextId;
}

public static Singleton getInstance(){
    if(instance == null){
        instance = new Singleton();
    }
    return instance;
}

}

这是Stack Trace:

java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.ObjectInputStream$BlockDataInputStream.readUnsignedShort(ObjectInputStream.java:2808)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2864)
at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:1072)
at com.digitalpyrite.assassin.server.Singleton.getNewID(Singleton.java:37)
at com.digitalpyrite.assassin.server.Main.doGet(Main.java:42)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

我遇到的问题是每次调用getNewID()方法时,在读取文件时都会抛出EOFException。它应该仅在程序第一次运行时抛出,此时文件是新创建的并且为空。我尝试了各种不同的方法来读取这个文件,但都失败了。扫描程序抛出NoSuchElementException,Reader在读取文本时返回null等。我做错了什么?

1 个答案:

答案 0 :(得分:0)

首先,在评论之外:此字符串"/Users/Timmy/Desktop/IDFile.txt"看起来非常容易出错。在你的情况下可能不是问题,但你仍然应该对其进行非硬编码 - 就像这样,这是一个潜在的错误。


关于EOF问题:首先,FileInputStreamFileOutputStream与同一个File对象互动。由于您没有交错使用它们,因此您应该在使用OutputStream时将InputStream的开头移至:

...
fileIn.close();
fileIn = null;

fileOut = new ObjectOutputStream(new FileOutputStream(file));
...

第二:你正在使用不同的编码进行写作。您应该使用writeUTF()才能阅读readUTF()

    idString = fileIn.readUTF();
...
fileOut.writeUTF(Long.toString(nextId) + "\n");

如果您选择这样做,请删除"\n"换行符,否则Long.parseLong() 正确解析输入字符串。最好只使用.readLong().writeLong()(因为您无论如何都要使用OIS / OOS);那样你就可以避免处理字符串了:

        lastId = fileIn.readLong();
...
fileOut.writeLong(nextId);