CodeGym /وبلاگ جاوا /Random-FA /کار با کلاس های BuffreredReader و InputStreamReader را تم...
John Squirrels
مرحله
San Francisco

کار با کلاس های BuffreredReader و InputStreamReader را تمرین کنید

در گروه منتشر شد
سلام! درس امروز برای سهولت به دو بخش تقسیم می شود. برخی از موضوعات قدیمی را که قبلاً به آنها اشاره کرده بودیم، تکرار می کنیم و برخی از ویژگی های جدید را در نظر می گیریم :) بیایید با اولی شروع کنیم. شما در حال حاضر یک کلاس مانند BufferedReaderچندین بار. امیدوارم وقت نکرده باشید این جمله را فراموش کنید:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
قبل از خواندن ادامه مطلب، سعی کنید به خاطر داشته باشید که هر جزء - System.in, InputStreamReader, BufferedReader- مسئول چه چیزی است و چرا به آن نیاز است. یادت افتاد؟ اگر نه، جای نگرانی نیست. :) اگر چیزی را فراموش کرده اید، این درس را که به کلاس های کتابخوان اختصاص دارد، دوباره بخوانید. ما به طور خلاصه به یاد می آوریم که هر یک از آنها چه کاری می توانند انجام دهند. System.in- این یک جریان برای دریافت داده از صفحه کلید است.  در اصل، برای اجرای منطق لازم برای خواندن متن کافی است. اما، همانطور که به یاد دارید، System.inفقط می توانید بایت ها را بخوانید، نه کاراکترها:
public class Main {

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

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
اگر این کد را اجرا کنیم و حرف سیریلیک "Й" را وارد کنیم، خروجی به صورت زیر خواهد بود:

Й
208
153
10 
کاراکترهای سیریلیک 2 بایت در حافظه اشغال می کنند و روی صفحه نمایش داده می شوند. عدد 10 نمایش دهدهی یک کاراکتر تغذیه خط است، یعنی با فشار دادن Enter. خواندن بایت ها بسیار لذت بخش است، بنابراین استفاده از آن System.inچندان راحت نیست. برای خواندن صحیح حروف سیریلیک (و سایر حروف)، ما InputStreamReaderبه عنوان لفاف استفاده می کنیم:
public class Main {

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

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
ما همان حرف "Й" را وارد می کنیم، اما نتیجه این بار متفاوت است:

Й 
1049 
10
InputStreamReaderدو بایت (208 و 153) به عدد 1049 تبدیل شده است. خواندن کاراکترها به این معنی است. 1049 با حرف سیریلیک "Й" مطابقت دارد. ما به راحتی می توانیم خودمان را متقاعد کنیم که این درست است:
public class Main {

   public static void main(String[] args) throws IOException {
       char x = 1049;
       System.out.println(x);
   }
}
خروجی کنسول:

Й
و به عنوان forBufferedReader(و به طور کلی، BufferedAnythingYouWant)، از کلاس های بافر برای بهینه سازی عملکرد استفاده می شود. دسترسی به یک منبع داده (فایل، کنسول، منبع وب) از نظر عملکرد بسیار گران است. بنابراین برای کاهش تعداد دسترسی ها، BufferedReaderداده ها را در یک بافر خاص می خواند و جمع می کند و از آنجا دریافت می کنیم. در نتیجه، تعداد دفعاتی که به منبع داده دسترسی پیدا می‌کند کاهش می‌یابد - احتمالاً با چندین مرتبه بزرگی! یکی دیگر از BufferedReaderویژگی های و مزیت آن نسبت به معمولی InputStreamReader، روش بسیار مفیدی است readLine()که تمام خطوط داده را می خواند، نه اعداد جداگانه. این، البته، هنگام برخورد با متون بزرگ بسیار راحت است. در اینجا خطوط خواندن به نظر می رسد:
public class Main {

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

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println ("The user entered the following text:");
       System.out.println(s);
       reader.close();
   }
}

BufferedReader+InputStreamReader is faster than InputStreamReader alone 
The user entered the following text: 
BufferedReader+InputStreamReader is faster than InputStreamReader alone
کار با کلاس های BuffreredReader و InputStreamReader را تمرین کنید - 2البته BufferedReaderبسیار انعطاف پذیر است. شما محدود به کار با صفحه کلید نیستید. به عنوان مثال، شما می توانید داده ها را مستقیماً از وب، به سادگی با ارسال URL مورد نیاز به یک خواننده بخوانید:
public class URLReader {

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

       URL oracle = new URL("https://www.oracle.com/index.html");
       BufferedReader in = new BufferedReader(
               new InputStreamReader(oracle.openStream()));

       String inputLine;
       while ((inputLine = in.readLine()) != null)
           System.out.println(inputLine);
       in.close();
   }
}
با عبور از مسیر فایل می توانید داده ها را از یک فایل بخوانید:
public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("testFile.txt");
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));

       String str;

       while ((str = reader.readLine()) != null)   {
           System.out.println (str);
       }

       reader.close();
   }
}

جایگزینی System.out

حال بیایید نگاهی به قابلیت جالبی بیندازیم که قبلاً به آن دست نزده ایم. همانطور که مطمئناً به یاد دارید، Systemکلاس دارای دو فیلد ثابت است - System.inو  System.out. این برادران دوقلو اشیاء جریانی هستند. System.inهست یک InputStream. و System.out یک است PrintStream. در حال حاضر، ما در مورد صحبت خواهیم کرد  System.out. اگر وارد کد منبع کلاس شویم System، این را می بینیم:
public final class System {
……………...
public final static PrintStream out = null;
 …………
}
بنابراین،  System.out  به سادگی یک متغیر استاتیک معمولی ازSystem کلاس است. هیچ چیز جادویی در مورد آن وجود ندارد :) outمتغیر یک مرجع است PrintStream. در اینجا یک سوال جالب وجود دارد: وقتی System.out.println()اجرا می شود، چرا دقیقاً خروجی به کنسول می رود و جای دیگری نیست؟ و آیا می توان این را به نحوی تغییر داد؟ به عنوان مثال، فرض کنید می خواهیم داده ها را از کنسول بخوانیم و در یک فایل متنی بنویسیم. آیا می توان به نوعی این را به سادگی با استفاده  System.outاز کلاس های خواننده و نویسنده اضافی اجرا کرد؟ در واقع، این است :) و ما می توانیم این کار را انجام دهیم، حتی اگر System.outمتغیر با اصلاح کننده مشخص شده باشد final!  کار با کلاس های BuffreredReader و InputStreamReader را تمرین کنید - 3پس برای تحقق این امر به چه چیزی نیاز داریم؟ اول از همه، ما به یک PrintStreamشی جدید برای جایگزینی شی فعلی نیاز داریم. شی فعلی که Systemبه طور پیش فرض در کلاس تنظیم شده است، اهداف ما را برآورده نمی کند: به کنسول اشاره می کند. شما باید یک فایل جدید ایجاد کنید که به یک فایل متنی اشاره می کند - "مقصد" برای داده های ما. دوم، ما باید بدانیم که چگونه یک مقدار جدید به System.outمتغیر اختصاص دهیم. شما نمی توانید از یک عملگر انتساب ساده استفاده کنید، زیرا متغیر علامت گذاری شده است final. بیایید از آخر به عقب کار کنیم. همانطور که اتفاق می افتد، Systemکلاس متد مورد نیاز ما را دارد: setOut(). یک شی را می گیرد PrintStreamو آن را به عنوان مقصد برای خروجی تعیین می کند. این فقط چیزی است که ما نیاز داریم! تنها چیزی که باقی می ماند ایجاد یک PrintStreamشی است. این نیز آسان است:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
کد کامل به شکل زیر خواهد بود:
public class SystemRedirectService {

   public static void main(String arr[]) throws FileNotFoundException
   {
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
       /* Save the current value of System.out in a separate variable so that later
       we can switch back to console output */

       PrintStream console = System.out;
       // Assign a new value to System.out
       System.setOut(filePrintStream);
       System.out.println("This line will be written to the text file");

       // Restore the old value of System.out
       System.setOut(console);
       System.out.println("But this line will be output to the console!");
   }
}
در نتیجه رشته اول در فایل متنی نوشته می شود و رشته دوم در کنسول نمایش داده می شود :) می توانید این کد را در IDE خود کپی کرده و اجرا کنید. فایل متنی را باز کنید و خواهید دید که رشته با موفقیت در آنجا نوشته شده است :) با این کار، درس ما به پایان رسید. امروز نحوه کار با استریم ها و خوانندگان را به یاد آوردیم. ما به یاد آوردیم که آنها چگونه با یکدیگر تفاوت دارند و در مورد برخی از قابلیت های جدید یاد گرفتیم System.outکه تقریباً در هر درس از آنها استفاده کرده ایم :) تا درس های بعدی!

ادامه مطلب:

نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION