سلام! درس امروز برای سهولت به دو بخش تقسیم می شود. برخی از موضوعات قدیمی را که قبلاً به آنها اشاره کرده بودیم، تکرار می کنیم و برخی از ویژگی های جدید را در نظر می گیریم :) بیایید با اولی شروع کنیم. شما در حال حاضر یک کلاس مانند
البته
پس برای تحقق این امر به چه چیزی نیاز داریم؟ اول از همه، ما به یک
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

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
! 
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
که تقریباً در هر درس از آنها استفاده کرده ایم :) تا درس های بعدی!
ادامه مطلب: |
---|
GO TO FULL VERSION