多数の小さなファイルをメモリに読み込む最速の方法は何ですか?

StackOverflow https://stackoverflow.com/questions/625420

質問

サーバーの起動ごとに最大50ファイルを読み取り、各テキストファイルの表現をメモリに配置する必要があります。各テキストファイルには独自の文字列があります(文字列ホルダーに使用するのに最適なタイプは?)。

ファイルをメモリに読み込む最速の方法は何ですか?また、メモリ内でテキストを操作できるようにテキストを保持するのに最適なデータ構造/タイプは何ですか?(主に検索と置換)

ありがとう

役に立ちましたか?

解決

メモリマッピングされたファイルは最速になります...次のようになります:

    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 よりも大幅に高速になります。

編集:

これについて少し調査した結果、お使いのOSによっては、代わりに新しい BufferedInputStream(new FileInputStream(file))を使用した方が良い場合があることがわかりました。ただし、すべてを一度にchar []に読み込むと、ファイルのサイズが最悪のように聞こえます。

したがって、 BufferedInputStream は、すべてのプラットフォームでほぼ一貫したパフォーマンスを提供する必要がありますが、メモリマップファイルは、基盤となるOSによって低速または高速になる場合があります。パフォーマンスが重要なすべてのものと同様に、コードをテストし、何が最適かを確認する必要があります。

編集:

OKここにいくつかのテストがあります(最初のテストはファイルをディスクキャッシュに入れるために2回行われます)。

私はrt.jarクラスファイルで実行し、ハードドライブに抽出しました。これはWindows 7ベータx64の下です。それは、合計94,706,637バイトの16784ファイルです。

最初の結果...

(ディスクキャッシュの設定を取得するために最初の手順が繰り返されることを思い出してください)

  • 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);
    }
}

他のヒント

最も効率的な方法は次のとおりです。

  • ファイルの長さを決定する( File.length()
  • 同じサイズ(またはわずかに大きい)の文字バッファーを作成します
  • ファイルのエンコードを決定します
  • new InputStreamReader(new FileInputStream(file)、encoding)を使用して読み取り
  • read()を1回呼び出して、whileファイルをバッファに読み込みます。 read()は早期に戻る場合があることに注意してください(ファイル全体を読み取ったわけではありません)。その場合、次のバッチを読み取るために、オフセットを付けて再度呼び出します。
  • 文字列を作成します: new String(buffer)

起動時に一度検索と置換が必要な場合は、String.replaceAll()を使用します。

繰り返し行う必要がある場合は、StringBuilderの使用を検討してください。 replaceAll()はありませんが、これを使用して文字配列を適切に操作できます(-&gt;メモリの割り当てなし)。

それは言った:

  1. コードをできるだけ短くシンプルにします。
  2. パフォーマンスを測定する
  3. 遅すぎるので修正してください。

実行に0.1秒しかかからない場合、このコードを高速に実行するために多くの時間を無駄にする理由はありません。

まだパフォーマンスの問題がある場合は、すべてのテキストファイルをJARに入れてクラスパスに追加し、Class.getResourceAsStream()を使用してファイルを読み取ることを検討してください。 Javaクラスパスからの読み込みは高度に最適化されています。

それは、テキストファイルの内部構造とそれらを使用して何をするかによって大きく異なります。

ファイルはKey-Value辞書(つまり、「プロパティ」ファイル)ですか? XML? JSON?それらの標準構造があります。

形式的な構造を持っている場合は、JavaCCを使用してファイルのオブジェクト表現を構築することもできます。

それ以外の場合、それらが単なるデータの塊である場合は、ファイルを読み取り、文字列に入れます。

編集:検索と置換について-juste use StringのreplaceAll関数

GoogleでJavaのIO速度に関する既存のテストを検索した後、TofuBearのテストケースが完全に目を開いたと言わざるを得ません。自分のプラットフォームで彼のテストを実行して、あなたにとって最速のものを確認する必要があります。

彼のテストを実行し、自分のコードをいくつか追加した後(元のコードを投稿したことをTofuBearにクレジット)、独自のカスタムバッファーを使用するか、BufferedInputStreamを使用することで、さらに高速になる可能性があります。

残念なことに、NIO ByteBufferはうまく機能しませんでした。

注:静的byte []バッファーは数ミリ秒削り取られましたが、静的ByteBuffersは実際に処理時間を増やしました! コードに何か問題がありますか?

いくつかのテストを追加しました:

  1. ArrayTest_CustomBuffering(データを自分のバッファーに直接読み込む)

  2. ArrayTest_CustomBuffering_StaticBuffer(最初に一度だけ作成される静的バッファーにデータを読み取ります)

  3. FileChannelArrayByteBuffer(NIO ByteBufferを使用して独自のbyte []配列をラップ)

  4. FileChannelAllocateByteBuffer(.allocateでNIO ByteBufferを使用)

  5. FileChannelAllocateByteBuffer_StaticBuffer(4と同じですが、静的バッファーを使用)

  6. FileChannelAllocateDirectByteBuffer(NIO ByteBufferと.allocateDirectを使用)

  7. FileChannelAllocateDirectByteBuffer_StaticBuffer(6と同じですが、静的バッファーを使用)

ここに私の結果があります:抽出されたrt.jarでWindows Vistaとjdk1.6.0_13を使用: 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);
     } 
 }

従来のアプローチでは、速度が制限されます。あるアプローチから次のアプローチへの大きな違いがわかるかどうかはわかりません。

操作全体を高速化できるビジネス上のトリックに集中します。

たとえば、すべてのファイルを読み取って、それぞれの元のファイルのタイムスタンプを持つ単一のファイルに保存した場合、実際にファイルを開かずにファイルが変更されたかどうかを確認できます。 (つまり、単純なキャッシュ)。

問題がGUIの迅速な起動であった場合、最初の画面が表示された後にバックグラウンドスレッドでファイルを開く方法を見つけることができます。

OSはファイルにかなり適しています。これがバッチプロセスの一部である場合(ユーザーI / Oがない場合)、Javaを起動する前に、何かを使用してすべてのファイルを1つの大きなファイルに追加するバッチファイルから開始できますこのように:

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

その後、file.allを開くだけです(これがどれほど速くなるかはわかりませんが、たった今述べた条件に対する最速のアプローチでしょう)

多くの場合、速度の問題を解決するには、視点を少し拡大し、新しいパラメーターを使用して解決策を完全に再考する必要がある場合が多いと思います。通常、既存のアルゴリズムの変更は、読みやすさを犠牲にして速度をわずかに向上させるだけです。

Commons IO FileUtils.readFileToString(File)などの標準ツールを使用して、1秒以内にすべてのファイルを読み取ることができるはずです

writeStringToFile(File、String)を使用して、変更されたファイルも保存できます。

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

ところで:50は多数のファイルではありません。典型的なPCは100K以上のファイルを持つことができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top