未完成复制/上载时读取文件内容

时间:2013-03-04 11:22:54

标签: java file concurrency

每隔5秒(例如),服务器会检查文件是否已添加到特定目录。如果是,它会读取并处理它们。相关文件可能非常大(例如100+ Mo),因此将它们复制/上传到所述目录可能会很长。

如果服务器尝试访问尚未完成复制/上传的文件,该怎么办? JAVA如何管理这些并发访问?它取决于服务器的操作系统吗?


我试了一下,将一个~1300000行的TXT文件(即大约200 Mo)从远程服务器复制到我的本地计算机:大约需要5秒钟。在这段时间内,我运行以下JAVA类:

public static void main(String[] args) throws Exception {

    String local = "C:\\large.txt";

    BufferedReader reader = new BufferedReader(new FileReader(local));
    int lines = 0;
    while (reader.readLine() != null)
        lines++;
    reader.close();

    System.out.println(lines + " lines");

}

我得到以下异常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2882)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:515)
    at java.lang.StringBuffer.append(StringBuffer.java:306)
    at java.io.BufferedReader.readLine(BufferedReader.java:345)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at main.Main.main(Main.java:15)

一旦文件完成复制后运行类,我得到预期的输出(即1229761 lines),因此异常不是由于文件的大小(正如我们在第一篇文章中所想的那样)地点)。 JAVA在后台做什么,引发了这个OutOfMemoryError例外?

2 个答案:

答案 0 :(得分:1)

为什么使用缓冲读卡器来计算线数?

来自javadoc:     从字符输入流中读取文本,缓冲字符,以便有效地读取字符,数组和行。

这意味着它将“缓冲”,即。保存,内存中的整个文件导致堆栈转储。试试FileReader。

答案 1 :(得分:1)

  
    

JAVA如何管理这些并发访问?它取决于服务器的操作系统吗?

  

这取决于具体的操作系统。如果您在单个JVM AsynchronousFileChannel (new in 1.7)类中运行副本和服务器可能会有很大帮助。但是,如果客户端和服务器由不同的JVM(或者更多,在不同的计算机上启动)表示,那么它们都变成了特定于平台的。

来自JavaDoc for AsynchronousFileChannel:

  
    

与FileChannel一样,此类实例提供的文件视图保证与同一程序中其他实例提供的同一文件的其他视图一致。但是,此类的实例提供的视图可能会也可能不会与其他同时运行的程序所看到的视图一致,这是由于底层操作系统执行的缓存和网络文件系统协议引起的延迟。无论这些其他程序的编写语言是什么,以及它们是在同一台机器上运行还是在其他机器上运行,都是如此。任何此类不一致的确切性质都取决于系统,因此未指明。