CodeGym /وبلاگ جاوا /Random-FA /ورودی/خروجی در جاوا کلاس های FileInputStream، FileOutputS...
John Squirrels
مرحله
San Francisco

ورودی/خروجی در جاوا کلاس های FileInputStream، FileOutputStream و BufferedInputStream

در گروه منتشر شد
"سلام! در درس امروز، ما گفتگوی خود را در مورد جریان های ورودی و خروجی در جاوا ( Java I/O ) ادامه خواهیم داد. این اولین درس در مورد این موضوع نیست و مطمئنا آخرین درس نیز نخواهد بود ورودی/خروجی در جاوا  کلاس های FileInputStream، FileOutputStream و BufferedInputStream - 1:) اتفاق می‌افتد، زبان جاوا راه‌های زیادی برای کار با I/O ارائه می‌کند. کلاس‌های زیادی وجود دارند که این عملکرد را پیاده‌سازی می‌کنند، بنابراین ما آنها را به چندین درس تقسیم کرده‌ایم - بنابراین از همان ابتدا گیج نشوید :) در گذشته دروس، BufferedReaderو همچنین کلاس‌های InputStreamانتزاعی و چندین نسل را لمس کردیم OutputStream. امروز ما 3 کلاس جدید را در نظر خواهیم گرفت: FileInputStream,  FileOutputStream, و  BufferedInputStream.

کلاس FileOutputStream

هدف اصلی کلاس FileOutputStreamنوشتن بایت در یک فایل است. هیچ چیز پیچیده ای نیست :) FileOutputStreamیکی از پیاده سازی های OutputStreamکلاس انتزاعی است. در سازنده، اشیاء این کلاس یا مسیر فایل هدف (جایی که بایت ها باید نوشته شوند) یا یک Fileشی را می گیرند. نمونه هایی از هر کدام را بررسی می کنیم:
public class Main {

   public static void main(String[] args) throws IOException {

       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!";

       fileOutputStream.write(greetings.getBytes());
       fileOutputStream.close();
   }
}
هنگام ایجاد Fileشی، مسیر مورد نظر را به سازنده منتقل کردیم. ما نیازی به ایجاد آن از قبل نداریم: اگر وجود نداشته باشد، برنامه آن را ایجاد خواهد کرد. شما همچنین می توانید بدون ایجاد یک شی اضافی، به سادگی یک رشته را با مسیر عبور دهید:
public class Main {

    public static void main(String[] args) throws IOException {

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");
       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!";

       fileOutputStream.write(greetings.getBytes());
       fileOutputStream.close();
   }
}
نتیجه در هر دو مورد یکسان خواهد بود. ما می توانیم فایل خود را باز کنیم و موارد زیر را در آنجا مشاهده کنیم:

Hi! Welcome to CodeGym — The best site for would-be programmers!
اما یک نکته ظریف در اینجا وجود دارد. سعی کنید کدهای مثال بالا را چندین بار پشت سر هم اجرا کنید. سپس به فایل نگاه کنید و به این سوال پاسخ دهید: چند خط دارد؟ فقط یکی. اما شما کد را چندین بار اجرا کردید. معلوم می‌شود که داده‌ها هر بار بازنویسی می‌شوند - داده‌های قدیمی با جدید جایگزین می‌شوند. اگر برای ما مناسب نیست و باید به صورت متوالی در فایل بنویسیم، چه کار کنیم؟ اگر بخواهیم احوالپرسی خود را سه بار پشت سر هم به یک فایل بنویسیم چه؟ همه چیز خیلی ساده است. از آنجایی که زبان نمی تواند بداند در هر مورد به چه رفتاری نیاز داریم، FileOutputStreamسازنده می تواند یک پارامتر اضافی را انتخاب کند - boolean append. اگر مقدار آن true باشد، داده ها در انتهای فایل نوشته می شوند. اگر نادرست باشد (و به طور پیش فرض نادرست است)، هر داده قدیمی پاک می شود و با داده جدید جایگزین می شود. بیایید این را با اجرای کد اصلاح شده خود سه بار بررسی کنیم:
public class Main {

   public static void main(String[] args) throws IOException {

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);
       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!\r\n";

       fileOutputStream.write(greetings.getBytes());
       fileOutputStream.close();
   }
}
محتویات فایل:

Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers!
حالا فرق کرده! هنگام استفاده از کلاس های I/O، این ویژگی را فراموش نکنید. close()زمانی بود که ساعت‌ها روی کارها وقت می‌گذاشتم، ساعت‌ها ذهنم را درگیر می‌کردم، سعی می‌کردم بفهمم که چگونه داده‌هایم از فایل‌ها ناپدید می‌شوند :) و البته، درست مانند سایر کلاس‌های I/O، استفاده از این روش را فراموش نکنید. برای آزاد کردن منابع

کلاس FileInputStream

FileInputStreamهدف معکوس دارد - خواندن بایت ها از یک فایل . همانطور که FileOutputStreamارث می برد OutputStream، این کلاس از InputStreamکلاس انتزاعی مشتق می شود. ما چند خط متن را در فایل " test.txt " خود خواهیم نوشت:

"So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters"
ورودی/خروجی در جاوا  کلاس های FileInputStream، FileOutputStream و BufferedInputStream - 2در اینجا به نظر می رسد که خواندن داده ها از یک فایل با استفاده از FileInputStream:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);

       }
   }
}
یک بایت از فایل را می خوانیم، بایت های خوانده شده را به کاراکتر تبدیل می کنیم و در کنسول نمایش می دهیم. و این هم خروجی کنسول:

So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters

کلاس BufferedInputStream

فکر می کنم، با توجه به دانش درس های گذشته، می توانید به راحتی بگویید چرا ما به کلاس نیاز داریم BufferedInputStreamو چه مزیت هایی در مقایسه با آن دارد FileInputStream:) ما قبلاً با جریان های بافر مواجه شده ایم، بنابراین سعی کنید قبل از ادامه خواندن حدس بزنید (یا به خاطر بسپارید) :) جریان های بافر عمدتاً برای بهینه سازی ورودی/خروجی مورد نیاز هستند. دسترسی به یک منبع داده، مانند خواندن از روی یک فایل، از نظر کارایی یک عملیات پرهزینه است و دسترسی به یک فایل برای خواندن هر بایت بیهوده است. به همین دلیل است که BufferedInputStreamداده ها را نه یک بایت در یک زمان، بلکه در بلوک می خواند و به طور موقت آنها را در یک بافر مخصوص ذخیره می کند. این به ما اجازه می دهد تا با کاهش تعداد دفعات دسترسی به فایل، برنامه را بهینه کنیم. بیایید ببینیم این چه شکلی است:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
در اینجا ما یک BufferedInputStreamشی ایجاد کردیم. سازنده آن نمونه ای از InputStreamکلاس یا هر یک از فرزندان آن را می گیرد، بنابراین این FileInputStreamکار را خواهد کرد. به عنوان یک آرگومان اضافی، اندازه بافر را بر حسب بایت می گیرد. به لطف این استدلال، اکنون داده ها از فایل نه یک بایت در یک زمان، بلکه 200 بایت در یک زمان خوانده می شوند! تصور کنید چقدر تعداد دسترسی به فایل ها را کاهش داده ایم. برای مقایسه عملکرد، می‌توانید یک فایل متنی بزرگ (چند مگابایت متن) بگیرید و مدت زمان خواندن و خروجی آن را بر حسب میلی‌ثانیه با استفاده از FileInputStreamو BufferedInputStream. در اینجا کدی وجود دارد که هر دو گزینه را نشان می دهد:
public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");
       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;
       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();
       System.out.println((date1.getTime() - date.getTime()));
   }
}


public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();
       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");

       int i;
       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }


       Date date1 = new Date();
       System.out.println((date1.getTime() - date.getTime()));
   }
}
هنگام خواندن یک فایل 1.5 مگابایتی در رایانه من، FileInputStreamکار را در 3500 میلی ثانیه انجام دادم، اما BufferedInputStreamآن را در 1700 میلی ثانیه مدیریت کردم. همانطور که می بینید، جریان بافر کار را بهینه کرد و آن را نصف کرد! :) ما به مطالعه کلاس های I/O ادامه خواهیم داد - به زودی شما را می بینیم!
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION