Какой самый быстрый способ чтения большого количества маленьких файлов в память? - PullRequest
19 голосов
/ 09 марта 2009

Мне нужно прочитать ~ 50 файлов при каждом запуске сервера и поместить представление каждого текстового файла в память. Каждый текстовый файл будет иметь свою собственную строку (какой тип лучше использовать для держателя строки?).

Какой самый быстрый способ чтения файлов в память и какова лучшая структура / тип данных для хранения текста, чтобы я мог манипулировать им в памяти (в основном, для поиска и замены)?

Спасибо

Ответы [ 6 ]

30 голосов
/ 09 марта 2009

Файл с отображением в памяти будет быстрее ... примерно так:

    final File             file;
    final FileChannel      channel;
    final MappedByteBuffer buffer;

    file    = new File(fileName);
    fin     = new FileInputStream(file);
    channel = fin.getChannel();
    buffer  = channel.map(MapMode.READ_ONLY, 0, file.length());

, а затем приступить к чтению из байтового буфера.

Это будет значительно быстрее, чем FileInputStream или FileReader.

РЕДАКТИРОВАТЬ:

После небольшого исследования этого выясняется, что в зависимости от вашей ОС вам может быть лучше использовать вместо него новый BufferedInputStream(new FileInputStream(file)). Однако чтение всего этого сразу в char [] размер файла звучит как худший способ.

Таким образом, BufferedInputStream должен обеспечивать примерно одинаковую производительность на всех платформах, в то время как отображаемый файл памяти может быть медленным или быстрым в зависимости от базовой ОС. Как и все, что критично к производительности, вы должны протестировать свой код и посмотреть, что работает лучше.

EDIT:

Хорошо, вот несколько тестов (первый выполняется дважды, чтобы получить файлы в кэш диска).

Я запускал его на файлах класса rt.jar, извлеченных на жесткий диск, это под Windows 7 beta x64. Это 16784 файла с общим объемом 94 706 637 байт.

Первые результаты ...

(помните, первое повторяется, чтобы получить настройку дискового кэша)

  • ArrayTest

    • время = 83016
    • байт = 118641472
  • ArrayTest

    • время = 46570
    • байт = 118641472
  • DataInputByteAtATime

    • время = 74735
    • байт = 118641472
  • DataInputReadFully

    • время = 8953
    • байт = 118641472
  • MemoryMapped

    • время = 2320
    • байт = 118641472

Вот код ...

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.HashSet;
import java.util.Set;

public class Main
{
    public static void main(final String[] argv)
    {
        ArrayTest.main(argv);
        ArrayTest.main(argv);
        DataInputByteAtATime.main(argv);
        DataInputReadFully.main(argv);
        MemoryMapped.main(argv);
    }
}

abstract class Test
{
    public final void run(final File root)
    {
        final Set<File> files;
        final long      size;
        final long      start;
        final long      end;
        final long      total;

        files = new HashSet<File>();
        getFiles(root, files);

        start = System.currentTimeMillis();

        size = readFiles(files);

        end = System.currentTimeMillis();
        total = end - start;

        System.out.println(getClass().getName());
        System.out.println("time  = " + total);
        System.out.println("bytes = " + size);
    }

    private void getFiles(final File      dir,
                          final Set<File> files)
    {
        final File[] childeren;

        childeren = dir.listFiles();

        for(final File child : childeren)
        {
            if(child.isFile())
            {
                files.add(child);
            }
            else
            {
                getFiles(child, files);
            }
        }
    }

    private long readFiles(final Set<File> files)
    {
        long size;

        size = 0;

        for(final File file : files)
        {
            size += readFile(file);
        }

        return (size);
    }

    protected abstract long readFile(File file);
}

class ArrayTest
    extends Test
{
    public static void main(final String[] argv)
    {
        final Test test;

        test = new ArrayTest();
        test.run(new File(argv[0]));
    }

    protected long readFile(final File file)
    {
        InputStream stream;

        stream = null;

        try
        {
            final byte[] data;
            int          soFar;
            int          sum;

            stream = new BufferedInputStream(new FileInputStream(file));
            data   = new byte[(int)file.length()];
            soFar  = 0;

            do
            {
                soFar += stream.read(data, soFar, data.length - soFar);
            }
            while(soFar != data.length);

            sum = 0;

            for(final byte b : data)
            {
                sum += b;
            }

            return (sum);
        }
        catch(final IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(stream != null)
            {
                try
                {
                    stream.close();
                }
                catch(final IOException ex)
                {
                    ex.printStackTrace();
                }
            }
        }

        return (0);
    }
}

class DataInputByteAtATime
    extends Test
{
    public static void main(final String[] argv)
    {
        final Test test;

        test = new DataInputByteAtATime();
        test.run(new File(argv[0]));
    }

    protected long readFile(final File file)
    {
        DataInputStream stream;

        stream = null;

        try
        {
            final int fileSize;
            int       sum;

            stream   = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            fileSize = (int)file.length();
            sum      = 0;

            for(int i = 0; i < fileSize; i++)
            {
                sum += stream.readByte();
            }

            return (sum);
        }
        catch(final IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(stream != null)
            {
                try
                {
                    stream.close();
                }
                catch(final IOException ex)
                {
                    ex.printStackTrace();
                }
            }
        }

        return (0);
    }
}

class DataInputReadFully
    extends Test
{
    public static void main(final String[] argv)
    {
        final Test test;

        test = new DataInputReadFully();
        test.run(new File(argv[0]));
    }

    protected long readFile(final File file)
    {
        DataInputStream stream;

        stream = null;

        try
        {
            final byte[] data;
            int          sum;

            stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            data   = new byte[(int)file.length()];
            stream.readFully(data);

            sum = 0;

            for(final byte b : data)
            {
                sum += b;
            }

            return (sum);
        }
        catch(final IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(stream != null)
            {
                try
                {
                    stream.close();
                }
                catch(final IOException ex)
                {
                    ex.printStackTrace();
                }
            }
        }

        return (0);
    }
}

class DataInputReadInChunks
    extends Test
{
    public static void main(final String[] argv)
    {
        final Test test;

        test = new DataInputReadInChunks();
        test.run(new File(argv[0]));
    }

    protected long readFile(final File file)
    {
        DataInputStream stream;

        stream = null;

        try
        {
            final byte[] data;
            int          size;
            final int    fileSize;
            int          sum;

            stream   = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            fileSize = (int)file.length();
            data     = new byte[512];
            size     = 0;
            sum      = 0;

            do
            {
                size += stream.read(data);

                sum = 0;

                for(int i = 0; i < size; i++)
                {
                    sum += data[i];
                }
            }
            while(size != fileSize);

            return (sum);
        }
        catch(final IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(stream != null)
            {
                try
                {
                    stream.close();
                }
                catch(final IOException ex)
                {
                    ex.printStackTrace();
                }
            }
        }

        return (0);
    }
}
class MemoryMapped
    extends Test
{
    public static void main(final String[] argv)
    {
        final Test test;

        test = new MemoryMapped();
        test.run(new File(argv[0]));
    }

    protected long readFile(final File file)
    {
        FileInputStream stream;

        stream = null;

        try
        {
            final FileChannel      channel;
            final MappedByteBuffer buffer;
            final int              fileSize;
            int                    sum;

            stream   = new FileInputStream(file);
            channel  = stream.getChannel();
            buffer   = channel.map(MapMode.READ_ONLY, 0, file.length());
            fileSize = (int)file.length();
            sum      = 0;

            for(int i = 0; i < fileSize; i++)
            {
                sum += buffer.get();
            }

            return (sum);
        }
        catch(final IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(stream != null)
            {
                try
                {
                    stream.close();
                }
                catch(final IOException ex)
                {
                    ex.printStackTrace();
                }
            }
        }

        return (0);
    }
}
4 голосов
/ 09 марта 2009

Самый эффективный способ:

  • Определить длину файла (File.length())
  • Создание буфера символов с таким же размером (или немного большим)
  • Определить кодировку файла
  • Используйте new InputStreamReader (new FileInputStream(file), encoding), чтобы прочитать
  • Считать файл while в буфер одним вызовом read (). Обратите внимание, что read () может вернуться рано (не прочитав весь файл). В этом случае вызовите его снова со смещением, чтобы прочитать следующий пакет.
  • Создать строку: new String(buffer)

Если вам нужно найти и заменить один раз при запуске, используйте String.replaceAll ().

Если вам нужно сделать это несколько раз, вы можете рассмотреть возможность использования StringBuilder. Он не имеет replaceAll (), но вы можете использовать его для манипулирования массивом символов на месте (-> без выделения памяти).

Это говорит:

  1. Сделайте ваш код максимально коротким и простым.
  2. Измерение производительности
  3. Это слишком медленно, исправьте это.

Нет смысла тратить много времени на то, чтобы этот код работал быстро, если для его выполнения требуется всего 0,1 с.

Если у вас все еще есть проблемы с производительностью, попробуйте поместить все текстовые файлы в JAR, добавить его в classpath и использовать Class.getResourceAsStream () для чтения файлов. Загрузка вещей из Java classpath высоко оптимизирована.

1 голос
/ 11 мая 2009

После поиска в Google существующих тестов скорости ввода-вывода в Java, я должен сказать, что контрольный пример TofuBear полностью открыл мне глаза. Вы должны запустить его тест на своей собственной платформе, чтобы увидеть, что быстрее для вас.

После запуска его теста и добавления нескольких моих собственных (спасибо TofuBear за публикацию его исходного кода), кажется, вы можете получить еще большую скорость, используя свой собственный буфер по сравнению с BufferedInputStream.

К моему ужасу, NIO ByteBuffer не работал хорошо.

ПРИМЕЧАНИЕ. Статический буфер байтов [] сбрасывается на несколько мс, но статические байтовые буферы фактически увеличивают время обработки! Что-то не так с кодом ??

Я добавил несколько тестов:

  1. ArrayTest_CustomBuffering (чтение данных непосредственно в мой собственный буфер)

  2. ArrayTest_CustomBuffering_StaticBuffer (чтение данных в статический буфер, который создается только один раз в начале)

  3. FileChannelArrayByteBuffer (используйте NIO ByteBuffer и оборачивайте свой собственный массив byte [])

  4. FileChannelAllocateByteBuffer (используйте NIO ByteBuffer с .allocate)

  5. FileChannelAllocateByteBuffer_StaticBuffer (аналогично 4, но со статическим буфером)

  6. FileChannelAllocateDirectByteBuffer (используйте NIO ByteBuffer с .allocateDirect)

  7. FileChannelAllocateDirectByteBuffer_StaticBuffer (аналогично 6, но со статическим буфером)

Вот мои результаты: с использованием Windows Vista и jdk1.6.0_13 на извлеченном файле rt.jar: ArrayTest
время = 2075
байт = 2120336424
ArrayTest
время = 2044
байт = 2120336424
ArrayTest_CustomBuffering
время = 1903
байт = 2120336424
ArrayTest_CustomBuffering_StaticBuffer
время = 1872
байт = 2120336424
DataInputByteAtATime
время = 2668
байт = 2120336424
DataInputReadFully
время = 2028
байт = 2120336424
MemoryMapped
время = 2901
байт = 2120336424
FileChannelArrayByteBuffer
время = 2371
байт = 2120336424
FileChannelAllocateByteBuffer
время = 2356
байт = 2120336424
FileChannelAllocateByteBuffer_StaticBuffer
время = 2668
байт = 2120336424
FileChannelAllocateDirectByteBuffer
время = 2512
байт = 2120336424
FileChannelAllocateDirectByteBuffer_StaticBuffer
время = 2590
байт = 2120336424

Моя взломанная версия кода TofuBear:

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.MappedByteBuffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.HashSet;
import java.util.Set;
public class Main { 
    public static void main(final String[] argv)     { 
        ArrayTest.mainx(argv);
        ArrayTest.mainx(argv);
        ArrayTest_CustomBuffering.mainx(argv);
        ArrayTest_CustomBuffering_StaticBuffer.mainx(argv);
        DataInputByteAtATime.mainx(argv);
        DataInputReadFully.mainx(argv);
        MemoryMapped.mainx(argv);
        FileChannelArrayByteBuffer.mainx(argv);
        FileChannelAllocateByteBuffer.mainx(argv);
        FileChannelAllocateByteBuffer_StaticBuffer.mainx(argv);
        FileChannelAllocateDirectByteBuffer.mainx(argv);
        FileChannelAllocateDirectByteBuffer_StaticBuffer.mainx(argv);
     } 
 } 
abstract class Test { 
    static final int BUFF_SIZE = 20971520;
    static final byte[] StaticData = new byte[BUFF_SIZE];
    static final ByteBuffer StaticBuffer =ByteBuffer.allocate(BUFF_SIZE);
    static final ByteBuffer StaticDirectBuffer = ByteBuffer.allocateDirect(BUFF_SIZE);
    public final void run(final File root)     { 
        final Set<File> files;
        final long      size;
        final long      start;
        final long      end;
        final long      total;
        files = new HashSet<File>();
        getFiles(root, files);
        start = System.currentTimeMillis();
        size = readFiles(files);
        end = System.currentTimeMillis();
        total = end - start;
        System.out.println(getClass().getName());
        System.out.println("time  = " + total);
        System.out.println("bytes = " + size);
     } 
    private void getFiles(final File dir,final Set<File> files)     { 
        final File[] childeren;
        childeren = dir.listFiles();
        for(final File child : childeren)         { 
            if(child.isFile())             { 
                files.add(child);
             } 
            else             { 
                getFiles(child, files);
             } 
         } 
     } 
    private long readFiles(final Set<File> files)     { 
        long size;
        size = 0;
        for(final File file : files)         { 
            size += readFile(file);
         } 
        return (size);
     } 
    protected abstract long readFile(File file);
 } 
class ArrayTest    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new ArrayTest();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        InputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            int          soFar;
            int          sum;
            stream = new BufferedInputStream(new FileInputStream(file));
            data   = new byte[(int)file.length()];
            soFar  = 0;
            do             { 
                soFar += stream.read(data, soFar, data.length - soFar);
             } 
            while(soFar != data.length);
            sum = 0;
            for(final byte b : data)             { 
                sum += b;
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 

 class ArrayTest_CustomBuffering    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new ArrayTest_CustomBuffering();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        InputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            int          soFar;
            int          sum;
            stream = new FileInputStream(file);
            data   = new byte[(int)file.length()];
            soFar  = 0;
            do             { 
                soFar += stream.read(data, soFar, data.length - soFar);
             } 
            while(soFar != data.length);
            sum = 0;
            for(final byte b : data)             { 
                sum += b;
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 }

 class ArrayTest_CustomBuffering_StaticBuffer    extends Test { 



    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new ArrayTest_CustomBuffering_StaticBuffer();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        InputStream stream;
        stream = null;
        try         { 
            int          soFar;
            int          sum;
            final int    fileSize;
            stream = new FileInputStream(file);
            fileSize = (int)file.length();
            soFar  = 0;
            do             { 
                soFar += stream.read(StaticData, soFar, fileSize - soFar);
             } 
            while(soFar != fileSize);
            sum = 0;
            for(int i=0;i<fileSize;i++)             { 
                sum += StaticData[i];
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 }

class DataInputByteAtATime    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new DataInputByteAtATime();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        DataInputStream stream;
        stream = null;
        try         { 
            final int fileSize;
            int       sum;
            stream   = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            fileSize = (int)file.length();
            sum      = 0;
            for(int i = 0; i < fileSize; i++)             { 
                sum += stream.readByte();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 
class DataInputReadFully    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new DataInputReadFully();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        DataInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            int          sum;
            stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            data   = new byte[(int)file.length()];
            stream.readFully(data);
            sum = 0;
            for(final byte b : data)             { 
                sum += b;
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 
class DataInputReadInChunks    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new DataInputReadInChunks();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        DataInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            int          size;
            final int    fileSize;
            int          sum;
            stream   = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            fileSize = (int)file.length();
            data     = new byte[512];
            size     = 0;
            sum      = 0;
            do             { 
                size += stream.read(data);
                sum = 0;
                for(int i = 0;
 i < size;
 i++)                 { 
                    sum += data[i];
                 } 
             } 
            while(size != fileSize);
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 
class MemoryMapped    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new MemoryMapped();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        FileInputStream stream;
        stream = null;
        try         { 
            final FileChannel      channel;
            final MappedByteBuffer buffer;
            final int              fileSize;
            int                    sum;
            stream   = new FileInputStream(file);
            channel  = stream.getChannel();
            buffer   = channel.map(MapMode.READ_ONLY, 0, file.length());
            fileSize = (int)file.length();
            sum      = 0;

            for(int i = 0; i < fileSize; i++)             { 
                sum += buffer.get();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 

 class FileChannelArrayByteBuffer    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new FileChannelArrayByteBuffer();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        FileInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            final FileChannel      channel;
            final ByteBuffer       buffer;
            int                    nRead=0;
            final int              fileSize;
            int                    sum;
            stream = new  FileInputStream(file);
            data   = new byte[(int)file.length()];
            buffer = ByteBuffer.wrap(data);

            channel  = stream.getChannel();
            fileSize = (int)file.length();
            nRead += channel.read(buffer);

            buffer.rewind();
            sum      = 0;
            for(int i = 0; i < fileSize; i++)             { 
                sum += buffer.get();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 

 class FileChannelAllocateByteBuffer    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new FileChannelAllocateByteBuffer();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        FileInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            final FileChannel      channel;
            final ByteBuffer       buffer;
            int                    nRead=0;
            final int              fileSize;
            int                    sum;
            stream = new  FileInputStream(file);
            //data   = new byte[(int)file.length()];
            buffer = ByteBuffer.allocate((int)file.length());

            channel  = stream.getChannel();
            fileSize = (int)file.length();
            nRead += channel.read(buffer);

            buffer.rewind();
            sum      = 0;
            for(int i = 0; i < fileSize; i++)             { 
                sum += buffer.get();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 } 

 class FileChannelAllocateDirectByteBuffer    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new FileChannelAllocateDirectByteBuffer();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        FileInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            final FileChannel      channel;
            final ByteBuffer       buffer;
            int                    nRead=0;
            final int              fileSize;
            int                    sum;
            stream = new  FileInputStream(file);
            //data   = new byte[(int)file.length()];
            buffer = ByteBuffer.allocateDirect((int)file.length());

            channel  = stream.getChannel();
            fileSize = (int)file.length();
            nRead += channel.read(buffer);

            buffer.rewind();
            sum      = 0;
            for(int i = 0; i < fileSize; i++)             { 
                sum += buffer.get();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 }

 class FileChannelAllocateByteBuffer_StaticBuffer    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new FileChannelAllocateByteBuffer_StaticBuffer();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        FileInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            final FileChannel      channel;
            int                    nRead=0;
            final int              fileSize;
            int                    sum;
            stream = new  FileInputStream(file);
            //data   = new byte[(int)file.length()];
            StaticBuffer.clear();
            StaticBuffer.limit((int)file.length());
            channel  = stream.getChannel();
            fileSize = (int)file.length();
            nRead += channel.read(StaticBuffer);

            StaticBuffer.rewind();
            sum      = 0;
            for(int i = 0; i < fileSize; i++)             { 
                sum += StaticBuffer.get();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 }

 class FileChannelAllocateDirectByteBuffer_StaticBuffer    extends Test { 
    public static void mainx(final String[] argv)     { 
        final Test test;
        test = new FileChannelAllocateDirectByteBuffer_StaticBuffer();
        test.run(new File(argv[0]));
     } 
    protected long readFile(final File file)     { 
        FileInputStream stream;
        stream = null;
        try         { 
            final byte[] data;
            final FileChannel      channel;
            int                    nRead=0;
            final int              fileSize;
            int                    sum;
            stream = new  FileInputStream(file);
            //data   = new byte[(int)file.length()];
            StaticDirectBuffer.clear();
            StaticDirectBuffer.limit((int)file.length());
            channel  = stream.getChannel();
            fileSize = (int)file.length();
            nRead += channel.read(StaticDirectBuffer);

            StaticDirectBuffer.rewind();
            sum      = 0;
            for(int i = 0; i < fileSize; i++)             { 
                sum += StaticDirectBuffer.get();
             } 
            return (sum);
         } 
        catch(final IOException ex)         { 
            ex.printStackTrace();
         } 
        finally         { 
            if(stream != null)             { 
                try                 { 
                    stream.close();
                 } 
                catch(final IOException ex)                 { 
                    ex.printStackTrace();
                 } 
             } 
         } 
        return (0);
     } 
 }
1 голос
/ 09 марта 2009

Это во многом зависит от внутренней структуры ваших текстовых файлов и от того, что вы собираетесь с ними делать.

Являются ли словари значений ключей файлов (т.е. файлы "свойств")? XML? JSON? У вас есть стандартные структуры для них.

Если они имеют формальную структуру, вы также можете использовать JavaCC для построения объектного представления файлов.

В противном случае, если это просто капли данных, прочитайте файлы и поместите их в строку.

Редактировать: о поиске и замене всего использования Функция String replaceAll .

0 голосов
/ 10 марта 2009

Вы сможете прочитать все файлы за секунду, используя стандартные инструменты, такие как Commons IO FileUtils.readFileToString (File)

Вы также можете использовать writeStringToFile (File, String) для сохранения измененного файла.

http://commons.apache.org/io/api-release/index.html?org/apache/commons/io/FileUtils.html

Кстати: 50 - это не большое количество файлов. Типичный ПК может иметь файлы размером 100 КБ или более.

0 голосов
/ 09 марта 2009

Любой традиционный подход будет ограничен в скорости. Я не уверен, что вы увидите большую разницу от одного подхода к другому.

Я бы сконцентрировался на бизнес-трюках, которые могли бы ускорить всю операцию.

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

Если вашей проблемой было быстрое получение графического интерфейса, вы можете найти способ открыть файлы в фоновом потоке после отображения вашего первого экрана.

ОС может работать с файлами довольно хорошо, если это часть пакетного процесса (без пользовательского ввода-вывода), вы можете начать с пакетного файла, который добавляет все файлы в один большой перед запуском java, используя что-то как это:

echo "file1" > file.all
type "file1" >> file.all
echo "file2" >> file.all
type "file2" >> file.all

Тогда просто откройте file.all (я не уверен, насколько это будет быстрее, но, вероятно, это самый быстрый подход к условиям, которые я только что изложил)

Полагаю, я просто говорю, что чаще всего решение проблемы скорости часто требует небольшого расширения вашей точки зрения и полного переосмысления решения с использованием новых параметров. Модификации существующего алгоритма обычно дают незначительные улучшения скорости за счет читабельности.

...