使用Web应用程序上传大文件

时间:2012-09-19 17:49:51

标签: java file-upload file-io nio bulk

目前还无法获得给定目标的环境,因此,我无法尝试,只能依靠分析!

我的目标可以分为以下几个不同的步骤:

  1. 使用愚蠢的“上传文件”页面上传大文件(最多 100GB ) - 由于用户需要(哑)前端并且不愿意ftp档案等。
  2. 提供上述前端的Web应用程序将托管在低端机器上 - 2GB RAM和40GB HDD,此Web应用程序不会存储本地计算机上的大文件的任何部分,但必须“快速”写入它是一个高端的远程Linux机器
  3. 对于每一步,我都会突出我的方法,关注点和疑问:

    • 我提到this线程让我感到困惑,因为我打算使用带有上传页面的Spring MVC创建一个愚蠢的Web应用程序 - 我是否需要进入HTML5等或简单的Web应用程序会满足吗?

    • 考虑到2GB内存,Web应用程序将获得不到1GB的内存。如果代码没有严格编写,我担心可能会出现'OutOfMemoryError' - 我必须确保从流中获得一个小块,比如说一次必须读取10MB并写入远程Linux机器的文件。 假设我在Controller Servlet的doPost(...)中,我做了一些关于如何进行并且感到困惑的阅读:

            /**
               * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
               *      response)
               */
              protected void doPost(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {
                  // TODO Auto-generated method stub
      
                  InputStream fis = request.getInputStream();
                  int i = 0;
      
                  /* Approach - 1 : Plain old byte-by-byte method */
                  Socket socket = new Socket("192.168.90.20", 22);
                  OutputStream remoteOpStream = socket.getOutputStream();
      
                  while ((i = fis.read()) != -1) {
                      remoteOpStream.write(i);
                  }
      
                  /* clean-up */
      
                  /* Approach - 2 : NIO */
                  ByteBuffer byteBuff = ByteBuffer.allocate(10000);/* read 10MB of data */
      
                  ReadableByteChannel rdbyc = Channels.newChannel(request
                          .getInputStream());
      
                  File remoteFile = new File("192.168.90.20/Remote_Linux_Folder");/*
                                                                                   * Dunno
                                                                                   * how
                                                                                   * to
                                                                                   * create
                                                                                   * a
                                                                                   * File
                                                                                   * on a
                                                                                   * remote
                                                                                   * Linux
                                                                                   * machine
                                                                                   */
                  FileOutputStream remoteFos = new FileOutputStream(remoteFile);
                  FileChannel writableChannel = remoteFos.getChannel();
      
                  while (true/* dunno how to loop till all the data is read! */) {
                      rdbyc.read(byteBuff);
                      writableChannel.write(byteBuff);
                  }
      
                  /* clean-up */
      
              }
      

    我需要一些方法,其中本地计算机上的数据存储是最小的 - 代码只是从输入流中读取n个字节并将其写入远程计算机

    我相信NIO是要走的路但是我无法确定我必须如何进行 - 请指导一下。

1 个答案:

答案 0 :(得分:0)

我会将一个FixedSizeQueue和popAll()数据从QueueStream中实现到另一台计算机。可能有双缓冲,只是为网络/带宽问题提供缓冲。