ورود

توجه ! این یک نسخه آرشیو شده میباشد و در این حالت شما عکسی را مشاهده نمیکنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : مشکل : لیمیت بودن file_get_contents و fread به 2 گیگابایت



hoka
March 29th, 2017, 23:24
سلام دوستان بنده نیاز دارم فایلی حجیم رو در php بخونم . متاسفانه fread و file_get_contents هر دو ارور 2 گیگ رو میدن

مثل ارور زیر


Warning: file_get_contents(): content truncated from 7351551328 to 2147483647 bytes in
چطوری میتونم این محدودیت رو بردارم ؟

سرور اختصاصی هست

Azade.Kaveh
March 29th, 2017, 23:43
جسارتا چه داده ای هست ؟ نوع فایل رو بفرمایید تا راهکار اساسی اعلام گردد

hoka
March 29th, 2017, 23:57
text هست قربان

Azade.Kaveh
March 30th, 2017, 00:05
text هست قربان

خوب کارتوناشتباهه عزیز واسه داده های متنی حجیم سعی کنید به صورت تفکیک شده و حدالامکان از دیتابیس استفاده کنید.

توضیح بیشتری بدین تا روش های بهینه سازی و تقسیم اطلاعات رو بدیم خدمتتون.

hoka
March 30th, 2017, 00:22
ما از دیتابیس فایل هارو آوردیم روی فایل به دلیل سرعت بیشتر . فعلا راه حل همین هست که فایل رو کامل بدون لیمیت بخونیم

AtrafNet
March 30th, 2017, 10:46
سلام
پیشنهاد میکنم از این روش خط به خط فایل رو پردازش کنید:



<?php
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
} else {
// error opening the file.
}


در این روش اطلاعات خط به خط خونده میشه و در متغیر line$ قرار میگیره اما خوبیش اینه که هیچ وقت نیاز به پر کردن حافظه RAM با کل 2 گیگ فایل نیست و اطلاعات فقط خط به خط buffer میشن.
البته حتی با این روش هم با اینکه احتمالاً مشکل RAM دیگه پیش نمیاد ولی به دلیل طولانی شدن پردازش 2 گیگ فایل اگر Request با مرورگر هستش به احتمال زیاد با خطای Time Out مواجه میشه مگر اینکه حجم فایل رو تیکه تیکه تر در هر Request جدا پردازش کنید.
منبع کد: http://stackoverflow.com/questions/13246597/how-to-read-a-file-line-by-line-in-php

Azade.Kaveh
March 30th, 2017, 13:18
سلام
پیشنهاد میکنم از این روش خط به خط فایل رو پردازش کنید:



<?php
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
} else {
// error opening the file.
}


در این روش اطلاعات خط به خط خونده میشه و در متغیر line$ قرار میگیره اما خوبیش اینه که هیچ وقت نیاز به پر کردن حافظه RAM با کل 2 گیگ فایل نیست و اطلاعات فقط خط به خط buffer میشن.
البته حتی با این روش هم با اینکه احتمالاً مشکل RAM دیگه پیش نمیاد ولی به دلیل طولانی شدن پردازش 2 گیگ فایل اگر Request با مرورگر هستش به احتمال زیاد با خطای Time Out مواجه میشه مگر اینکه حجم فایل رو تیکه تیکه تر در هر Request جدا پردازش کنید.
منبع کد: http://stackoverflow.com/questions/13246597/how-to-read-a-file-line-by-line-in-php

ایشون به دلیل حجم بالا اصلا نمیتونن فایل رو بخونن بعدا شما از کجا درومدی میگی که پرداش ؟

اول باید داده خونده بشه تا بشه پردازشش کرد .

navid2zp
March 30th, 2017, 13:23
ایشون به دلیل حجم بالا اصلا نمیتونن فایل رو بخونن بعدا شما از کجا درومدی میگی که پرداش ؟

اول باید داده خونده بشه تا بشه پردازشش کرد .
کد اول به این دلیل با ارور مواجه میشه که کل فایل با اون دستور خونده میشه
کدی که دوست عزیز پیشنهاد دادن کل فایل رو نمی خونه و در رم ذخیره نمی کنه بلکه فایل رو باز می کنه و هر قسمتی رو که نیاز داشته باشید می خونه
در نتیجه اروری نمیگیرید
توضیحاتشون رو با دقت بیشتری بخونید

Azade.Kaveh
March 30th, 2017, 13:29
کد اول به این دلیل با ارور مواجه میشه که کل فایل با اون دستور خونده میشه
کدی که دوست عزیز پیشنهاد دادن کل فایل رو نمی خونه و در رم ذخیره نمی کنه بلکه فایل رو باز می کنه و هر قسمتی رو که نیاز داشته باشید می خونه
در نتیجه اروری نمیگیرید
توضیحاتشون رو با دقت بیشتری بخونید

کلا فانکشن fopen نمیتونه حجم بالا بخونه !

حالا ایشون اومدن اول خوندنش بعد اومدن لاین به لاین while کردن...

در ضمن اصلا فرض هم بگیریم که خونده شده باشه نه نشده ! یعنی بابت هر کوئری دیتابیس قراره 2 گیگ رم خورده بشه ؟ یعنی برای داشتن 100 کاربر آنلاین حداقل حداقل باید 200 گیگ رم در نظر گرفت !

کار باید از بیس درست باشه عزیز دل !

AtrafNet
March 30th, 2017, 13:50
کلا فانکشن fopen نمیتونه حجم بالا بخونه !

حالا ایشون اومدن اول خوندنش بعد اومدن لاین به لاین while کردن...

در ضمن اصلا فرض هم بگیریم که خونده شده باشه نه نشده ! یعنی بابت هر کوئری دیتابیس قراره 2 گیگ رم خورده بشه ؟ یعنی برای داشتن 100 کاربر آنلاین حداقل حداقل باید 200 گیگ رم در نظر گرفت !

کار باید از بیس درست باشه عزیز دل !



درسته این روش اصلاً اصولی نیست ولی جناب من و شما نمی دونیم که استارتر برای چه کاری می خوان شاید اصلاً اونی که تو ذهن ماست یعنی یه وب سایت که قراره query رو از فایل حجیم بخونه نباشه شاید یه پروژه کار شخصی باشه.
چون خودم بار ها کار هایی داشتم که اصلاً عمومی نبودن و تونستم به هر روش ناشیانه ای هم شده حلش کنم میگم :->

درباره fopen هم استارتر گفتن fread که داده ها رو می خونه ایراد میگیره جسارتاً fopen به تنهایی وظیفه خوندن و بافر کردن داده ها رو نداره بلکه فقط یه file pointer ایجاد میکنه که باهاش کار کنیم :)
http://php.net/manual/en/function.fopen.php

لینکی هم که از stackoverflow.com در پست قبل دادم رو مطالعه کنید حجم فایل پرسش کننده در اون لینک هم 1 گیگ هستش.

T.Toosi
March 30th, 2017, 13:54
کلا فانکشن fopen نمیتونه حجم بالا بخونه !

حالا ایشون اومدن اول خوندنش بعد اومدن لاین به لاین while کردن...

در ضمن اصلا فرض هم بگیریم که خونده شده باشه نه نشده ! یعنی بابت هر کوئری دیتابیس قراره 2 گیگ رم خورده بشه ؟ یعنی برای داشتن 100 کاربر آنلاین حداقل حداقل باید 200 گیگ رم در نظر گرفت !

کار باید از بیس درست باشه عزیز دل !

سلام، fopen تنها file handle resource به شما برمیگردونه و content فایل خوانده نمیشه فقط یک اشاره گر به فایل هست و شما محدودیتی برای fopen ندارید. تنها در خواندن فایل احتیاج به مموری پیدا میکنید که این مشکل را میتوانید با فایل پوینتر با خواندن به صورت لاین به لاین که دوستمون در بالا اشاره کردند حل کنید.

navid2zp
March 30th, 2017, 14:39
کلا فانکشن fopen نمیتونه حجم بالا بخونه !

حالا ایشون اومدن اول خوندنش بعد اومدن لاین به لاین while کردن...

در ضمن اصلا فرض هم بگیریم که خونده شده باشه نه نشده ! یعنی بابت هر کوئری دیتابیس قراره 2 گیگ رم خورده بشه ؟ یعنی برای داشتن 100 کاربر آنلاین حداقل حداقل باید 200 گیگ رم در نظر گرفت !

کار باید از بیس درست باشه عزیز دل !

خیر دوست عزیز می تونید برای فایل های حجم بالا هم استفاده کنید
بنده برای فایل های بالای 5 گیگ هم بدون مشکل استفاده کردم

باز دوستان توضیحات کاملتر دادند

hoka
March 30th, 2017, 16:00
دوستان عزیز ممنون از همه ی راهنمایی ها .


اول از همه پروژه شخصی هست این سرور هم فقط برای همین کار هست . کلا در هر لحظه فقط یک پردازش قرار هست اتفاق بیوفته پس مشکلی در منابع نخواهد بود


دوم بنده نیاز دارم فایل رو یکجا بخونم و نه خط به خط مگر نه با fread مقدار حجم رو کم میکردم . نیاز هست که کل فایل خونده بشه به دلیل اینکه میخوام قسمت های مشابه رو حذف کنم . و بعد از اون میخوام اون فایل رو مدام مورد سرچ قرار بدم .


حالا اگر راه حلی هست که بشه فایل حجیم تکست رو در سرور باز کرد ممنون میشم بفرمایید

AtrafNet
March 30th, 2017, 16:24
دوستان عزیز ممنون از همه ی راهنمایی ها .


اول از همه پروژه شخصی هست این سرور هم فقط برای همین کار هست . کلا در هر لحظه فقط یک پردازش قرار هست اتفاق بیوفته پس مشکلی در منابع نخواهد بود


دوم بنده نیاز دارم فایل رو یکجا بخونم و نه خط به خط مگر نه با fread مقدار حجم رو کم میکردم . نیاز هست که کل فایل خونده بشه به دلیل اینکه میخوام قسمت های مشابه رو حذف کنم . و بعد از اون میخوام اون فایل رو مدام مورد سرچ قرار بدم .


حالا اگر راه حلی هست که بشه فایل حجیم تکست رو در سرور باز کرد ممنون میشم بفرمایید


تو ویندوز نرم افزار EmEditor می تونه فایل های حجیم 4 گیگ به بالا هم باز کنه و هم خودش سیستم Compare جهت مقایسه دو فایل داره.
همینطوری گفتم اگر صرفاً فقط هدف باز کردن تغییراته شاید به دردتون بخوره.

ولی اگه هدف فقط با PHP هستش به نظرم این عدد 2147483647 که محدودیتش هست به واحد بایت هستش و اگه دو بار تقسیم بر 1024 کنیم میشه فهمید که محدودیتش روی 2048 مگابایت فیکس شده ولی مموری مورد نیاز شما 7351551328 بایت هست که میشه 7 گیگ.
اصولاً اگه منابع سخت افزاری RAM و CPU و همچنین سرعت IO بالایی داشته باشید شاید بشه با تغییر memory_limit به حجم های زیاد درستش کرد ولی اصولی نیست.
به نظرم بهتره روش های دیگه خوندن فایل مثل همین fread و fopen با fget و file و... هم برای خوندن کامل تست کنید ببینید با کدومش php منابع RAM کمتری مصرف میکنه بعدش من نمی دونم هدف شما چیه ولی ببینید آیا حداقل نمیشه مرحله رو جوری تیکه تیکه کرد؟ مثلاً یه مقدار از کار که انجام شد باقی اش رو بذارید برای دفعه بعد و از ادامه فایل شروع کنید؟

hoka
March 30th, 2017, 16:56
تو ویندوز نرم افزار EmEditor می تونه فایل های حجیم 4 گیگ به بالا هم باز کنه و هم خودش سیستم Compare جهت مقایسه دو فایل داره.
همینطوری گفتم اگر صرفاً فقط هدف باز کردن تغییراته شاید به دردتون بخوره.

ولی اگه هدف فقط با PHP هستش به نظرم این عدد 2147483647 که محدودیتش هست به واحد بایت هستش و اگه دو بار تقسیم بر 1024 کنیم میشه فهمید که محدودیتش روی 2048 مگابایت فیکس شده ولی مموری مورد نیاز شما 7351551328 بایت هست که میشه 7 گیگ.
اصولاً اگه منابع سخت افزاری RAM و CPU و همچنین سرعت IO بالایی داشته باشید شاید بشه با تغییر memory_limit به حجم های زیاد درستش کرد ولی اصولی نیست.
به نظرم بهتره روش های دیگه خوندن فایل مثل همین fread و fopen با fget و file و... هم برای خوندن کامل تست کنید ببینید با کدومش php منابع RAM کمتری مصرف میکنه بعدش من نمی دونم هدف شما چیه ولی ببینید آیا حداقل نمیشه مرحله رو جوری تیکه تیکه کرد؟ مثلاً یه مقدار از کار که انجام شد باقی اش رو بذارید برای دفعه بعد و از ادامه فایل شروع کنید؟

ببینید مموری لیمیت و کلا لیمیت ها روی بینهایت هست . مشکل با لیمیت بودن fread و file_get_contents هست که روی 2 گیگ لیمیت شدن

در مورد بخش بخش کردن هم خیر متاسفانه . چون معلوم نیست قسمت تکراری در کدوم بخش قرار میگیره نیاز دارم که فایل رو یک جا بخونم در php .

- - - Updated - - -

البته این 7 گیگ یکی از فایل ها هست فقط. مجموع فایل ها بیش از 20 گیگ هست

T.Toosi
March 30th, 2017, 21:55
ورژن php چند هست ؟ os سیستم 32 یا 64 بیت هست ؟

قراره 2 تا فایل همزمان مقایسه کنید ؟ یا قراره یک داده تکراری (که میدونید چی هست) در فایل حجیم پیدا و جایگزین کنید ؟

اگر سیستم 32 بیت هست مقدار حجم PHP_INT_MAX به صورت زیر حساب میشود :

2 به توان 32 منهای 1 : 2147483647 بایت یا همون 2 گیگ

اگر قرار 2 تا فایل را همزمان مقایسه کنید که کلا php رو بزارید کنار برای این کار، اگر یک داده ای دارید و میخواید در یک فایل حجیم پیدا و جایگزین کنید، به هم صورت خطی یا به صورت آفست خیلی راحت میتونید انجام بدید.

hoka
March 30th, 2017, 22:01
ورژن php چند هست ؟ os سیستم 32 یا 64 بیت هست ؟

قراره 2 تا فایل همزمان مقایسه کنید ؟ یا قراره یک داده تکراری (که میدونید چی هست) در فایل حجیم پیدا و جایگزین کنید ؟

اگر سیستم 32 بیت هست مقدار حجم PHP_INT_MAX به صورت زیر حساب میشود :

2 به توان 32 منهای 1 : 2147483647 بایت یا همون 2 گیگ

اگر قرار 2 تا فایل را همزمان مقایسه کنید که کلا php رو بزارید کنار برای این کار، اگر یک داده ای دارید و میخواید در یک فایل حجیم پیدا و جایگزین کنید، به هم صورت خطی یا به صورت آفست خیلی راحت میتونید انجام بدید.

2.6.32-642.15.1.el6.x86_64 #1 SMP Fri Feb 24 14:31:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
CentOS release 6.8 (Final)
php 5.6.30


عرضم به حضورتون قرار هست چندتا فایل رو اول از همه عبارات مشابه هشون رو حذف کنم preg_match_all و ... و بعد همرو یک فایل کنم و در اون فایل چیز هایی که میخوام رو پیدا کنم با preg_match

که در هردو بخش حجم فایل ها بیشتر از دو گیگ هست

از نظر کد نویسی مشکلی نیست ولی متاسفانه تا حالا به فایل بزرگ تر از 2 گیگ نخورده بودم که به این مشکل برخورد کنم

T.Toosi
March 30th, 2017, 22:08
2.6.32-642.15.1.el6.x86_64 #1 SMP Fri Feb 24 14:31:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
CentOS release 6.8 (Final)
php 5.6.30


عرضم به حضورتون قرار هست چندتا فایل رو اول از همه عبارات مشابه هشون رو حذف کنم preg_match_all و ... و بعد همرو یک فایل کنم و در اون فایل چیز هایی که میخوام رو پیدا کنم با preg_match

که در هردو بخش حجم فایل ها بیشتر از دو گیگ هست

از نظر کد نویسی مشکلی نیست ولی متاسفانه تا حالا به فایل بزرگ تر از 2 گیگ نخورده بودم که به این مشکل برخورد کنم

ورژن php رو 7 کنید باید مشکلتون حل بشه.

در int 64 بیت مقدار ماکزیموم حجم شما میشه : 9223372036854775808 بایت

الان داره از int سی و دو بیت استفاده میکنه که بیشتر از 2گیگ رو نمیتونه هندل کنه.

hoka
March 30th, 2017, 22:25
ورژن php رو 7 کنید باید مشکلتون حل بشه.

در int 64 بیت مقدار ماکزیموم حجم شما میشه : 9223372036854775808 بایت

الان داره از int سی و دو بیت استفاده میکنه که بیشتر از 2گیگ رو نمیتونه هندل کنه.

ورژن 7 الان حجم ماکزیمم چقدر میشه ؟

و ممنون میشم دستورات آپدیت php به 7 رو در دایرکت ادمین بفرمایید

hoka
March 31st, 2017, 02:32
متاسفانه ورژن 7 هم مشکل داشت و فایل بزرگ رو خوند ولی توی preg_match_all ارور گرفت
Warning: preg_match_all(): Subject is too long in