3

每 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异常?

4

2 回答 2

1

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

这取决于特定的操作系统。如果您在单个 JVM AsynchronousFileChannel(1.7 中的新功能)类中运行副本和服务器,可能会有很大帮助。但是,如果客户端和服务器由不同的 JVM 表示(甚至更多,在不同的机器上启动),这一切都变成了特定于平台的。

来自AsynchronousFileChannel 的 JavaDoc:

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

于 2013-03-05T07:46:58.663 回答
1

你为什么使用缓冲阅读器来计算行数?

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

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

于 2013-03-04T20:08:15.940 回答