عند معالجة الملفات الكبيرة، إذا كنت تستخدم FileInputStream أو FileOutputStream أو RandomAccessFile العادي لإجراء عمليات القراءة والكتابة بشكل متكرر، فسوف يتسبب ذلك في إبطاء العملية بسبب القراءة والكتابة المتكررة للذاكرة الخارجية، وفيما يلي تجربة مقارنة.
انسخ رمز الكود كما يلي:
اختبار الحزمة
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
اختبار الطبقة العامة {
public static void main(String[] args) {
يحاول {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
مجموع كثافة العمليات=0;
كثافة العمليات ن؛
long t1=System.currentTimeMillis();
يحاول {
بينما((n=fis.read())>=0){
مجموع+=ن;
}
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
long t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" time:"+t);
} قبض على (FileNotFoundException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
يحاول {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
مجموع كثافة العمليات=0;
كثافة العمليات ن؛
long t1=System.currentTimeMillis();
يحاول {
بينما((n=bis.read())>=0){
مجموع+=ن;
}
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
long t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" time:"+t);
} قبض على (FileNotFoundException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
MappedByteBuffer buffer=null;
يحاول {
buffer=new RandomAccessFile("/home/tobacco/test/res.txt"،"rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
مجموع كثافة العمليات=0;
كثافة العمليات ن؛
long t1=System.currentTimeMillis();
ل(int i=0;i<1253244;i++){
n=0x000000ff&buffer.get(i);
مجموع+=ن;
}
long t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" time:"+t);
} قبض على (FileNotFoundException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
}
}
ملف الاختبار هو ملف بحجم 1253244 بايت. نتائج الاختبار:
انسخ رمز الكود كما يلي:
المبلغ:220152087 الوقت:1464
المبلغ:220152087 الوقت:72
المبلغ:220152087 الوقت:25
يشير إلى أن بيانات القراءة صحيحة. حذف جزء معالجة البيانات.
انسخ رمز الكود كما يلي:
اختبار الحزمة
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
اختبار الطبقة العامة {
public static void main(String[] args) {
يحاول {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
مجموع كثافة العمليات=0;
كثافة العمليات ن؛
long t1=System.currentTimeMillis();
يحاول {
بينما((n=fis.read())>=0){
//مجموع+=ن;
}
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
long t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" time:"+t);
} قبض على (FileNotFoundException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
يحاول {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
مجموع كثافة العمليات=0;
كثافة العمليات ن؛
long t1=System.currentTimeMillis();
يحاول {
بينما((n=bis.read())>=0){
//مجموع+=ن;
}
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
long t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" time:"+t);
} قبض على (FileNotFoundException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
MappedByteBuffer buffer=null;
يحاول {
buffer=new RandomAccessFile("/home/tobacco/test/res.txt"،"rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
مجموع كثافة العمليات=0;
كثافة العمليات ن؛
long t1=System.currentTimeMillis();
ل(int i=0;i<1253244;i++){
//n=0x000000ff&buffer.get(i);
//مجموع+=ن;
}
long t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" time:"+t);
} قبض على (FileNotFoundException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
}
}
نتائج الاختبار:
انسخ رمز الكود كما يلي:
المجموع:0 الوقت:1458
المجموع:0 الوقت:67
المجموع:0 الوقت:8
يمكن ملاحظة أنه سيتم تحسين السرعة بشكل كبير عن طريق تعيين جزء أو كل الملف في الذاكرة للقراءة والكتابة.
وذلك لأن الملف المعين للذاكرة يقوم أولاً بتعيين الملف الموجود على الذاكرة الخارجية إلى منطقة مستمرة في الذاكرة، والتي يتم التعامل معها على أنها مصفوفة بايت. تعمل عمليات القراءة والكتابة مباشرة على الذاكرة، ثم تعيد تعيين منطقة الذاكرة إلى ملف الذاكرة الخارجية مما يوفر وقت القراءة والكتابة المتكررة لوحدة التخزين الخارجية ويقلل بشكل كبير من وقت القراءة والكتابة.