Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > NIO


Автор: Tony 21.11.2006, 01:10
Использовал постаянно NIO. Ну вродибы класс. Высокая производительность, новая технологоя и сантехники рекомендуйют ну каро4е 4ики - пики. Так я любитель поэкперементировать. 4то будет если скопировать файл размером в 1.5 Гига ,стандартным методом:  smile 
Код

try {
              FileChannel in = new FileInputStream("d:/1.zip").getChannel();
              FileChannel out = new FileOutputStream("d:/2.zip").getChannel();            
              in.transferTo(0, in.size(), out);              
              in.close();
              out.close();
            }catch(Exception e){
                e.printStackTrace();
            }

Так вот на 20 секунде компик завис  smile . 4ерез 20 секунд отвис и выволился супер Exception  smile 
Код

java.io.IOException: Not enough storage is available to process this command
    at sun.nio.ch.FileChannelImpl.map0(Native Method)
    at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:742).....

У кого какие соображения? При4ём компик Athlon 64 3500+ и 1GB DDR 800. Вот такие дела.

Автор: Goliath 21.11.2006, 01:46
Цитата(Tony @  21.11.2006,  01:10 Найти цитируемый пост)
Так вот на 20 секунде компик завис

Комп зависает или приложение?

Автор: Tony 21.11.2006, 02:23
комп

Автор: Tony 21.11.2006, 17:30
Код

 FileChannel in = new FileInputStream(new File("d:/1.zip")).getChannel();
             FileChannel out = new FileOutputStream (new File("d:/2.zip")).getChannel();
            // int count = 0;
             ByteBuffer buffer = ByteBuffer.allocate(12 * 1024);

             long start = System.currentTimeMillis();
             // result standart io 213610 ms byte[12 * 1024] 
             // allocate  byte buffer 212906 ms
             // allocateDirect byte buffer 211844 ms
             while (in.read(buffer)!= -1){
                 buffer.flip();
                 out.write(buffer);
                 buffer.clear();
             } 
             long end = System.currentTimeMillis();
             System.out.println(end-start);
             in.close();
             out.close();
            }catch(Exception e){
                e.printStackTrace();
            }

1.zip = 1.578.939 KB .Как видно результат НИО не очень впе4атлителен.

Автор: LSD 21.11.2006, 18:55
Каков размер файла подкачки, и какая стоит ОС и JVM (32-х разрядная или 64-х разрядная)?

Автор: Tony 21.11.2006, 20:16
WinXP 32, client jvm. 1536 мб файл подкачки.

Автор: LSD 21.11.2006, 22:29
Цитата(Tony @  21.11.2006,  20:16 Найти цитируемый пост)
WinXP 32, client jvm. 1536 мб файл подкачки.

Думаю что в этом то и проблема, по стеку видно что он пытается замапить файл на память (memory-mapped file). И ему элементарно нехватает адресного пространства (у пользовательского процесса под 32-х битной виндой адресное пространство 2Гб).
Было бы интерестно посмотреть как этот код будет работать под 64-х битной виндой и 64-х битной JVM.

Автор: Tony 22.11.2006, 13:31
Прсто если ползоватеь будет копировать моей программой испoльзующий transferTo метод,  файил размером 1ГБ ,то я услышу "хорошие" отзывы от него.

Автор: Goliath 22.11.2006, 18:39
Цитата(Tony @  22.11.2006,  13:31 Найти цитируемый пост)
Прсто если ползоватеь будет копировать моей программой испoльзующий transferTo метод,  файил размером 1ГБ ,то я услышу "хорошие" отзывы от него.

Насколько я знаю файл менеджеры производят копирование по кусочкам, а некоторые просто меняют данные в таблицы расположения фалов на жестком диске (неуверен что правильно назвал).

Автор: LSD 22.11.2006, 18:42
Сделай так:
Код
  public static final long MAX_COPY_SIZE = 128 * 1024 * 1024;

  public static void copy(String input, String output)
  {
    try
    {
      FileChannel in = new FileInputStream(new File(input)).getChannel();
      FileChannel out = new FileOutputStream(new File(output)).getChannel();

      long curPos = 0L;
      long size = in.size();
      while(curPos < size)
      {
        long toCopy = size - curPos;
        if(toCopy > MAX_COPY_SIZE)
          toCopy = MAX_COPY_SIZE;
        curPos += in.transferTo(curPos, toCopy, out);
      }

      in.close();
      out.close();
    }
    catch(IOException e)
    {
      e.printStackTrace();
    }
  }

Автор: Tony 22.11.2006, 22:03
Тоже самое 4то и 
Код

 while (in.read(buffer)!= -1){
                 buffer.flip();
                 out.write(buffer);
                 buffer.clear();
             } 


Автор: LSD 22.11.2006, 23:54
Таки в чем проблема?
У меня копирование с помощью NIO быстрее на 20-40 процентов.

Автор: Tony 22.11.2006, 23:58
Просто запостил тему 4тобы люди были осторожными при копирование больших файлов через TransferTo и TransferFrom. 

Автор: LSD 23.11.2006, 00:01
А.... Учтем smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)