ما هي أسرع طريقة لقراءة عدد كبير من الملفات الصغيرة في الذاكرة؟

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.

يحرر:

بعد قليل من التحقيق في هذا الأمر، اتضح أنه، اعتمادًا على نظام التشغيل لديك، قد يكون من الأفضل لك استخدام إصدار جديد BufferedInputStream(new FileInputStream(file)) بدلاً من.ومع ذلك، فإن قراءة كل شيء مرة واحدة في char[] حجم الملف يبدو أسوأ طريقة.

لذا BufferedInputStream يجب أن يوفر أداءً متسقًا تقريبًا على جميع الأنظمة الأساسية، بينما قد يكون ملف الذاكرة المعين بطيئًا أو سريعًا اعتمادًا على نظام التشغيل الأساسي.كما هو الحال مع كل ما هو مهم للأداء، يجب عليك اختبار التعليمات البرمجية الخاصة بك ومعرفة ما هو الأفضل.

يحرر:

حسنًا، إليك بعض الاختبارات (يتم إجراء الاختبار الأول مرتين لإدخال الملفات إلى ذاكرة التخزين المؤقت على القرص).

لقد قمت بتشغيله على ملفات فئة 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);
    }
}

نصائح أخرى

الطريقة الأكثر فعالية هي:

  • تحديد طول الملف (File.length())
  • قم بإنشاء مخزن مؤقت للحرف بنفس الحجم (أو أكبر قليلاً)
  • تحديد التشفير من الملف
  • يستخدم new InputStreamReader (new FileInputStream(file), encoding) ليقرأ
  • اقرأ الملف while في المخزن المؤقت باستدعاء واحد للقراءة ().لاحظ أن القراءة() قد تعود مبكرًا (عدم قراءة الملف بالكامل).في هذه الحالة، قم باستدعائها مرة أخرى مع الإزاحة لقراءة الدفعة التالية.
  • إنشاء السلسلة: new String(buffer)

إذا كنت بحاجة إلى البحث والاستبدال مرة واحدة عند بدء التشغيل، فاستخدم String.replaceAll().

إذا كنت بحاجة إلى القيام بذلك بشكل متكرر، فقد تفكر في استخدام StringBuilder.لا يحتوي على ReplaceAll() ولكن يمكنك استخدامه لمعالجة مصفوفة الأحرف في مكانها (-> لا يوجد تخصيص للذاكرة).

هكذا قال:

  1. اجعل الكود الخاص بك قصيرًا وبسيطًا قدر الإمكان.
  2. قياس الأداء
  3. إنه بطيء جدًا، قم بإصلاحه.

لا يوجد سبب لإضاعة الكثير من الوقت لجعل هذا الكود يعمل بسرعة إذا كان تنفيذه يستغرق 0.1 ثانية فقط.

إذا كنت لا تزال تواجه مشكلة في الأداء، ففكر في وضع جميع الملفات النصية في JAR، وإضافتها إلى مسار الفصل واستخدام Class.getResourceAsStream() لقراءة الملفات.تم تحسين تحميل الأشياء من Java classpath بشكل كبير.

وهذا يعتمد كثيرا على البنية الداخلية للملفات نصية وما كنت تنوي القيام به معهم.

هل الملفات القواميس قيمة المفتاح (أي "خصائص" الملفات)؟ XML؟ JSON؟ لديك هياكل موحدة لهؤلاء.

وإذا كان لديهم هيكل رسمي يمكنك أيضا استخدام JavaCC لبناء تمثيل كائن من الملفات.

وعلى خلاف ذلك، إذا كانت النقط فقط من البيانات، أيضا، قراءة الملفات ووضعها في سلسلة.

تعديل: حول البحث واستخدام جوست بديلا لها <لأ href = "http://java.sun.com/javase/6/docs/api/java/lang/String.html#replaceAll ( java.lang.String،٪ 20java.lang.String) "يختلط =" نوفولو noreferrer "> سلسلة من وظيفة replaceAll .

بعد البحث عبر Google عن الاختبارات الموجودة على سرعة الإدخال والإخراج في Java، يجب أن أقول إن حالة اختبار TofuBear فتحت عيني تمامًا.يجب عليك إجراء اختباره على النظام الأساسي الخاص بك لمعرفة ما هو الأسرع بالنسبة لك.

بعد إجراء اختباره وإضافة عدد قليل من الاختبارات الخاصة بي (يعود الفضل إلى TofuBear لنشر الكود الأصلي الخاص به)، يبدو أنك قد تحصل على سرعة أكبر باستخدام المخزن المؤقت المخصص الخاص بك مقابل.باستخدام BufferedInputStream.

مما أثار استياءي أن أداء NIO ByteBuffer لم يكن جيدًا.

ملحوظة:تم تقليص المخزن المؤقت للبايت الثابت [] لبضعة مللي ثانية، لكن ByteBuffers الثابت زاد بالفعل من وقت المعالجة! هل هناك خطأ في الكود؟؟

أضفت بعض الاختبارات:

  1. ArrayTest_CustomBuffering (قراءة البيانات مباشرة في المخزن المؤقت الخاص بي)

  2. ArrayTest_CustomBuffering_StaticBuffer (اقرأ البيانات في المخزن المؤقت الثابت الذي يتم إنشاؤه مرة واحدة فقط في البداية)

  3. FileChannelArrayByteBuffer (استخدم NIO ByteBuffer وقم بتغليف صفيف البايت [] الخاص بك)

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

وأي النهج التقليدي ستكون محدودة في السرعة. أنا لست متأكد من أنك سوف نرى الكثير من الفرق من نهج واحد إلى آخر.

وأود أن التركيز على الحيل التجارية التي يمكن أن تجعل من العملية برمتها بشكل أسرع.

وعلى سبيل المثال، إذا كنت تقرأ كل الملفات وتخزينها في ملف واحد مع الطوابع الزمنية من كل من الملف الأصلي، ثم هل يمكن أن تحقق لمعرفة ما إذا كان أي من الملفات قد تغيرت دون فتحها فعلا. (مخبأ بسيط، وبعبارة أخرى).

إذا مشكلتك كان الحصول على واجهة المستخدم الرسومية بسرعة، قد تجد وسيلة لفتح الملفات في موضوع الخلفية بعد ظهور الشاشة الأولى.

ونظام التشغيل يمكن أن تكون جيدة جدا مع الملفات، وإذا كان هذا هو جزء من عملية دفعة (أي مستخدم I / O)، هل يمكن أن تبدأ مع ملف دفعي التي بإلحاق كافة الملفات في واحدة كبيرة واحدة قبل إطلاق جافا، وذلك باستخدام شيء مثل هذا:

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

وبعد ذلك فقط مفتوحة file.all (لست متأكدا كيف أسرع بكثير وهذا سيكون، ولكن من المحتمل أن يكون النهج أسرع لظروف ذكرت فقط)

وأعتقد أنا فقط أقول أن في أكثر الأحيان، وإيجاد حل لقضية سرعة وغالبا ما يتطلب توسيع وجهة نظرك قليلا وإعادة التفكير تماما الحل باستخدام معايير جديدة. إدخال تعديلات على خوارزمية الموجودة عادة ما تعطي سوى تحسينات طفيفة السرعة على حساب سهولة القراءة.

ويجب أن تكون قادرا على قراءة كافة الملفات في أقل من ثانية واحدة باستخدام الأدوات القياسية مثل العموم IO FileUtils.readFileToString (ملف)

ويمكنك استخدام writeStringToFile (ملف، سلسلة) لحفظ الملف المعدلة كذلك.

HTTP: / /commons.apache.org/io/api-release/index.html؟org/apache/commons/io/FileUtils.html

وراجع للشغل: 50 ليس عدد كبير من الملفات. A PC نموذجي يمكن أن يكون 100K الملفات أو أكثر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top