سؤال

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

سؤالي هو أفضل طريقة لقراءة هذه المعلومات و "استيراد" في سلسلة تيار ؟ المشكلة مع هذا النهج (انظر أدناه) هو أنه عندما خلق تيار سلسلة مخازن يحصل على نسخ واستخدام الذاكرة الزوجي.

#include <fstream>
#include <sstream>

using namespace std;

int main() {
  ifstream is;
  is.open (sFilename.c_str(), ios::binary );

  // get length of file:
  is.seekg (0, std::ios::end);
  long length = is.tellg();
  is.seekg (0, std::ios::beg);

  // allocate memory:
  char *buffer = new char [length];

  // read data as a block:
  is.read (buffer,length);

  // create string stream of memory contents
  // NOTE: this ends up copying the buffer!!!
  istringstream iss( string( buffer ) );

  // delete temporary buffer
  delete [] buffer;

  // close filestream
  is.close();

  /* ==================================
   * Use iss to access data
   */

}
هل كانت مفيدة؟

المحلول

std::ifstream طريقة rdbuf(), أن عودة المؤشر إلى filebuf.يمكنك ثم "دفع" هذا filebuf في stringstream:

#include <fstream>
#include <sstream>

int main()
{
    std::ifstream file( "myFile" );

    if ( file )
    {
        std::stringstream buffer;

        buffer << file.rdbuf();

        file.close();

        // operations on the buffer...
    }
}

تحرير:كما مارتن نيويورك ملاحظات في التعليقات, هذا قد لا يكون الحل الأسرع منذ stringstream's operator<< قراءة filebuf حرف.قد ترغب في التحقق من جوابه حيث انه يستخدم ifstream's read الطريقة كما كنت تفعل ، ومن ثم تعيين stringstream العازلة إلى النقطة سابقا الذاكرة المخصصة.

نصائح أخرى

موافق.أنا لا أقول أن هذا سيكون أسرع من القراءة من الملف

ولكن هذا هو الأسلوب حيث يمكنك إنشاء المنطقة العازلة مرة واحدة بعد قراءة البيانات في المخزن المؤقت استخدامه مباشرة كمصدر stringstream.

N. B.ومن الجدير بالذكر أن std::ifstream مؤقتا.يقرأ البيانات من الملف (كبير نسبيا) قطع.تيار يتم تنفيذ عمليات ضد المخزن المؤقت فقط العودة إلى ملف آخر عند قراءة المزيد من البيانات المطلوبة.حتى قبل أن مص جميع البيانات في الذاكرة الرجاء التحقق من أن هذا هو عنق الزجاجة.

#include <fstream>
#include <sstream>
#include <vector>

int main()
{
    std::ifstream       file("Plop");
    if (file)
    {
        /*
         * Get the size of the file
         */
        file.seekg(0,std::ios::end);
        std::streampos          length = file.tellg();
        file.seekg(0,std::ios::beg);

        /*
         * Use a vector as the buffer.
         * It is exception safe and will be tidied up correctly.
         * This constructor creates a buffer of the correct length.
         *
         * Then read the whole file into the buffer.
         */
        std::vector<char>       buffer(length);
        file.read(&buffer[0],length);

        /*
         * Create your string stream.
         * Get the stringbuffer from the stream and set the vector as it source.
         */
        std::stringstream       localStream;
        localStream.rdbuf()->pubsetbuf(&buffer[0],length);

        /*
         * Note the buffer is NOT copied, if it goes out of scope
         * the stream will be reading from released memory.
         */
    }
}

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

شيء آخر أن نأخذ في الاعتبار هو أن ملف I/O هو دائما ما يكون أبطأ العملية.لوك Touraille هذا هو الحل الصحيح, ولكن هناك خيارات أخرى.قراءة الملف بأكمله في الذاكرة في وقت واحد سوف يكون أسرع بكثير من فصل يقرأ.

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