PDA

View Full Version : چند سوال در مورد کار با فایل و متد های flip و clear کلاس ByteBuffer



vahid-p
سه شنبه 09 اردیبهشت 1393, 01:33 صبح
سلام دوستان
سوال اولم اینه که تفاوت اصلی flip و clear چیه؟ هر دوشون اشاره گر رو به خونه اول بافر میبرن درسته؟ چیزی که خودم حدس میزنم با توجه به اینکه تو stackoverflow نوشته flip بین حالت خوندن و نوشتن تعویض میکنه و با توجه به عکس هایی که گذاشتن، تفاوت در اون limit اش هست؟ یعنی clear محدوده رو کل بافر میگیره، ولی flip تا اونجایی که خونده شده؟ اگه درسته لطفا سوالات بعدی رو چک کنید :خجالت:

سوال دوم اینه چطور میتونم عملیات خوندن سرعتش رو زیادتر کنم؟
اینم کدم :
FileInputStream fileInputStream=new FileInputStream("test.dat");
FileChannel fileChannel=fileInputStream.getChannel();
ByteBuffer buffer=ByteBuffer.allocateDirect(64*1024*1024);
buffer.clear();
int byteRead=0,i;
int numChar[]=new int[256];

long size=0;
long start=System.currentTimeMillis();
while((byteRead=fileChannel.read(buffer))!=-1){
buffer.flip();
size+=byteRead;
// for(i=0;i<byteRead;i++){
//// System.out.println(buffer.get(i));
// numChar++;
// }
buffer.clear();
}
long end=System.currentTimeMillis();
System.out.println("Time = "+(end-start));
System.out.println("Size = "+size);
قسمت // خورده قسمت بعدی سوالم هست. اما در مورد این کد آیا میتونم سریعترش کنم؟ بعضی وقتها تست میکنم برای فایل 1.5 گیگی، بدک نیست، ولی اکثرا 24 ثانیه طول میکشه. ولی کدی شبیه به همین رو برای همین فایل با c++ میزنم، در حد 2 الی 3 ثانیه میخونه. از اونجایی که java.nio باید سرعتش خیلی بیشتر از java.io باشه، اما اینجا تفاوت زیادی حاصل نمیشه.
در لینک روبرو ببینید چی گفته : http://www.idryman.org/blog/2013/09/28/java-fast-io-using-java-nio-api/
گفته : the java.nio API I sped the process from 194.054 seconds to 0.16 sec!
اینو برای یه فایل 355 MB ای گفته. پس برای 1.5 گیگ هم انتظاری حدود دو سه ثانیه داریم حداقل!

[B]سوال سوم در مورد اینه که چرا از نوع byte وقتی باینری میخونیم اعداد منفی هم بهمون میده و من اومدم بعلاوه 128 کردم که نتایج بازم اشتباهه. چون تو رنج 65 تا 117 که کاراکترهای الفبا هستند، یا تعداد کاراکتر ها صفرن، یا هم خیلی کمن. و از طرفی اگر بعلاوه 128 نکنم، رنج معادل عددی کاراکتر های حرفی درست میشه! به تناقض خوردم. اگر کد اسکی A 65 هست، پس باید اعداد اسکی بین 0 تا 255 باشه و بایت هایی که از فایل میخونیم هم تو این رنج باشه و عدد منفی نداشته باشیم! ولی متاسفانه داریم و اگر منفی ها رو حساب نکنیم، اونوقت سایز فایل و تعداد کاراکتر ها برابر نمیشن! همین مشکل با c++ نوشتم هم وجود داره. مگر یک بایت غیر از 0 تا 255 چی میتونه باشه؟!

vahid-p
سه شنبه 09 اردیبهشت 1393, 01:53 صبح
در مورد سوال سوم خودم به یه چیزایی پی بردم اونم اینکه از مکمل 2 استفاده شده ( در اصل یعنی char خودش میاد مکمل دو رو وقتی منفی هست میگیره؟ چون هر فایلی به هر حال باینری هست )
یعنی باید هر بار چک کنم اگه منفی بود مکمل 2 بگیرم؟ این که خودش کار رو کند میکنه!
byte x;
int y;
if(x<0){
y=~x+128;
}else{
y=x;
}
عجب استانداردهایی ساختن خداییش! حالا جالبیش اینه تو C++‎‎‎ که متغیر byte نداره و باید از char استفاده کنیم، باز منفی میگیره و تازه تو اون قسمت که نوشتم numChar[buffer[i]] اررور خارج از محدوده نمگیره، جاوا حداقل میگه outofbound !!!

vahid-p
سه شنبه 09 اردیبهشت 1393, 18:59 عصر
در مورد سوال دومم هم خودم به نتیجه رسیدم. در اصل سرعت جاوا خیلی هم خوب بود، ولی تفاوت اینکه سی پلاس پلاس سریع میخوند به این خاطر بود که چون فایل یه بار خونده شده بود، سیستم عامل اونو رو تو رم کش کرده بود ( با اینکه سایز فایل زیاد بود ) و دفعات بعد که میخوند دیگه از رو هارد نمیخوند و از روی رم بود :قهقهه:
مثلا با سی پلاس پلاس میشد 1.7 ثانیه. ولی همینکار رو با جاوا java.nio انجام دادم شد 0.7 ثانیه. فکر کنم ایشونی که لینک مطلبشو دادم هم این اشتباه منو انجام داده و فکر کرده یه فایل 355 مگابایتی در حد 0.16 ثانیه خونده :)
اینم سوال دومم که بر طرف شد. سوال اول هم فکر کنم همون چیزی که فکرشو میکردم درست بوده باشه.

به هر حال گفتم اینایی که خودم بهش پی بردم بنویسم، شاید سوال یکی دیگه باشه.