نوشتن متن با PrintWriter در جاوا و کاتلین

کلاس PrintWriter در جاوا و کاتلین

بررسی PrintWriter

با استفاده از PrintWriter در جاوا و کاتلین میتونیم داده ها رو به صورت متن در فایل بنویسیم.

همانطور که گفتیم کلاس File در جاوا از خوندن و نوشتن داخل فایل پشتیبانی نمیکنه و برای این کار باید از کلاس های دیگه در پکیج io استفاده کنیم.

یکی از این کلاس ها PrintWriter در جاوا است؛ کلاس PrintWriter برای نوشتن متن در فایل مورد استفاده قرار میگیره.

تا الان برای نوشتن خروجی در کنسول از قطعه کد زیر استفاده میکردید:

System.out.println(...)

فیلد استاتیک out در واقع از نوع PrintStream است در کلاس PrintStream متدهای print، println و printf تعریف شده.

همین متد ها برای کلاس PrintWriter نیز تعریف شده و با استفاده از این متد ها در PrintWriter میتونیم داده ها رو به صورت متن در فایل بنویسیم.

در زیر کانستراکتور و متد های پرکاربرد کلاس PrintWriter بیان شده.

java.io.PrintWriter
+PrintWriter(File)
با پاس دادن آبجکت File به عنوان پارامتر کانستراکتور یک نمونه از PrintWriter ایجاد میکنه.
+PrintWriter(String)
با پاس دادن مسیر فایل به صورت String به عنوان پارامتر کانستراکتور یک نمونه از PrintWriter ایجاد میکنه.
+PrintWriter(OutputStream)
یک نمونه ی جدید از PrintWriter با کمک OutputStream دیگه ای درست میکنه.
+print(String): void
مقدار String رو در فایل می نویسه.
+print(char): void
مقدار کاراکتر رو در فایل می نویسه.
+print(char[]): void
یک آرایه از کاراکتر رو در فایل مینویسه.
+print(Object): void
مقدار یک آبجکت رو در فایل مینویسه.
+print(int): void
مقدار int رو داخل فایل مینویسه.
+print(long): void
مقدار long رو در فایل مینویسه.
+print(float): void
مقدار float رو در فایل مینویسه.
+print(double): void
مقدار double رو در فایل مینویسه.
+print(boolean): void
مقدار boolean رو در فایل مینویسه.
+flush(): void
بعد از نوشتن تمام داده ها با متد flush اطمینان حاصل میکنیم داده ای در حافظه ی buffer برای نوشتن در فایل باقی نمیمونه.
+close(): void
عملیات flush رو انجام میده و سپس فایل رو میبنده اگه بعد از پایان کار این متد صدا زده نشه احتمال داره داده ها به درستی ذخیره نشن.
کلاس PrintWriter از متد های println و printf نیز پشتیبانی میکنه و کاربردی مشابه print دارن؛ برای خلاصه شدن از نوشتنشون خودداری کردیم.

در کلاس هایی که مختص خوندن و نوشتن در جاوا هستند،checked-exception انداخته شده و هنگام تعریفشون باید در بلوک try-catch قرار بگیرند.

راهنمایی

برای اکثر کلاس های io کافیه IOException رو به عنوان پارامتر بلوک catch تعریف کنیم.

مثال

در مثال زیر ابتدا برنامه بررسی میکنه فایل وجود داره یا خیر اگه وجود داشته باشه برنامه متوقف میشه. سپس اگه فایل وجود نداشته باشه فایل به صورت خودکار توسط PrintWriter در روت پروژه (بخاطر مسیری که تعریف کردیم) ایجاد میشه و سپس داده ها رو داخل فایل می نویسه و بعد از پایان کار با متد close فایل رو میبنده.

public static void main(String[] args){ File file = new File("user-info.txt"); if (file.exists()) { System.out.println("File is already exists"); System.exit(1); } PrintWriter output = null; try{ output = new PrintWriter(file); output.print("Created on: "); output.println(new Date()); output.print("John "); output.print("Smith "); output.println(24); }catch(IOException e){ System.out.println(e.getMessage()); }finally{ output.close(); } }
fun main(){ val file = File("user-info.txt") if(file.exists){ println("File is already exists") System.exit(1) } var output: PrintWriter try{ output = PrintWriter(file) output.print("Created on: ") output.println(new Date()) output.print("John ") output.print("Smith ") output.println(24) }catch(e: IOException){ println(e.getMessage()) }finally{ output.close() } }

با هر بار باز کردن فایل توسط PrintWriter، محتوای فایل پاک شده و محتوای جدید در فایل نوشته میشه؛ یکی از روش های جلوگیری از پاک شدن محتوای فایل هنگام باز شدن توسط PrintWriter استفاده از FileWriter به عنوان پارامتر PrintWriter است که در بخش آخر توضیح داده شده است.

فکر خوبیه برای بستن فایل، متد close رو داخل بدنه ی finally صدا بزنیم. اگر چه میتونیم داخل بدنه ی try متد close رو صدا بزنیم اما با صدا زدنش در finally مطمئن میشیم بعدش متدی برای خوندن و نوشتن صدا نزدیم.

معرفی try-with-resources

استفاده از try-with-resources در جاوا اجباری نیست اما برای مرتب تر شدن کد ها و جلو گیری از فراموش کردن صدا زدن متد close توصیه میشه.

گاهی اوقات برنامه نویسا فراموش میکنن متد close رو صدا بزنن برای همین از جاوا 7 به بعد try-with-resources معرفی شد با استفاده از try-with-resources کلاس هایی که از AutoClosable ارث بری میکنن به طور خودکار بدون نیاز به صدا زدن متد close بسته میشن.

توجه

کلاس Scanner در جاوا نیز از AutoClosable ارث میبره.

فرم کلی:

try(statement0; statement1; ...; statementN){ ... }catch(Exception e){ ... }

اگه بخوایم از PrintWriter با try-with-resources استفاده کنیم مثل زیر میشه:

try(PrintWriter output = new PrintWriter(...)){ output.print(...); ... }catch(IOException e){ ... }

در کاتلین به جای try-with-resources از تابع خطی use استفاده میکنیم.

val output = PrintWriter(...) output.use{ it.print(..) ... }

مثال

در مثال زیر از try-with-resources در جاوا و تابع use در کاتلین استفاده کردیم.

public static void main(String[] args){ File file = new File("user-info.txt"); try (Scanner input = new Scanner(System.in); PrintWriter output = new PrintWriter(file)){ System.out.println("Enter firstname: "); String firstName = input.next(); System.out.println("Enter lastname: "); String lastName = input.next(); System.out.println("Enter age to submit: "); int age = input.nextInt(); output.print("Created on "); output.println(new Date()); output.print(firstName); output.print(" "); output.print(lastName); output.print(" "); output.print(age); }catch (IOException e){ e.printStackTrace(); } }
fun main(){ File file = new File("user-info.txt"); val input = Scanner(System.in) var firstname: String var lastname: String var age: Int input.use{ println("Enter first name") firstname = it.next() println("Enter lastname ") lastname = it.next() println("Enter age to submit ") age = it.next() } val output = PrintWriter(file) output.use{ it.print("Created on ") it.println(Date()) it.print(firstname) it.print(" ") it.print(lastname) it.print(" ") it.println(age) } }

نوشتن داده ها در امتداد محتوای فایل

به طور پیشفرض هنگام باز کردن فایل توسط PrintWriter محتوای فایل پاک شده و فایل برای نوشتن محتوای جدید مورد استفاده قرار میگیره.

با کمک FileWriter میتونیم داده های از پیش ذخیره شده در فایل رو حفظ کرده و داده های جدید رو در ادامه ی داده های قبلی بنویسیم.

برای این کار باید مقدار پارامتر appendable کانستراکتور FileWriter رو true قرار بدیم و خود FileWriter رو به عنوان پارامتر به PrintWriter پاس بدیم.

PrintWriter output = new PrintWriter(new FileWriter(file, true));
val output = PrintWriter(FileWriter(file, true))

توجه

کلاس FileWriter یکی از کلاس های Output در جاوا است و مانند PrintWriter میتونیم مستقیم از متد های خودش استفاده کنیم.

خلاصه

- کلاس PrintWriter در جاوا برای نوشتن داده های متنی در فایل است.

- بعد از انجام عملیات خوندن و نوشتن باید با استفاده از متد close فایل رو ببندیم.

- با try-with-resources در جاوا کلاس هایی که از AutoClosable ارث بری میکنن بدون نیاز به صدا زدن متد close به طور خودکار در آخر کار بسته میشن.

- در کاتلین بجای try-with-resources از تابع use استفاده میکنیم.

- با کمک آبجکت FileWriter و true قرار دادن مقدار پارامتر appendable آن میتونیم از پاک شدن محتوای فایل هنگام باز شدن توسط PrintWriter جلوگیری کنیم.

arrow_drop_up
کپی شد!