چگونه در جاوا یک فایل متنی را بخوانیم

خلاصه
1404/09/28

خواندن یک فایل متنی در جاوا یک کار رایج است و روش‌های مختلفی برای انجام آن وجود دارد. در اینجا چند روش متداول با توضیحات و مثال آورده شده است: **1. استفاده از `BufferedReader`

چگونه در جاوا یک فایل متنی را بخوانیم

خواندن یک فایل متنی در جاوا یک کار رایج است و روش‌های مختلفی برای انجام آن وجود دارد. در اینجا چند روش متداول با توضیحات و مثال آورده شده است:

**1. استفاده از `BufferedReader` و `FileReader` (روش سنتی):**

این روش کلاسیک و پرکاربرد است. `FileReader` فایل را باز می‌کند و `BufferedReader` امکان خواندن خط به خط را فراهم می‌کند.

```java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile {

public static void main(String[] args) {

String filePath = "path/to/your/file.txt"; // مسیر فایل خود را اینجا قرار دهید

try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {

String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}

} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
e.printStackTrace();
}
}
}
```

* **`FileReader`:** فایل را برای خواندن باز می‌کند. مسیر فایل (filePath) را به عنوان ورودی می‌گیرد.
* **`BufferedReader`:** یک بافر برای خواندن کاراکترها فراهم می‌کند که خواندن را سریع‌تر می‌کند. `FileReader` را به عنوان ورودی می‌گیرد.
* **`try-with-resources`:** این یک بلوک `try` خاص است که تضمین می‌کند `BufferedReader` (و به طور ضمنی `FileReader`) پس از اتمام کار به طور خودکار بسته می‌شود، حتی اگر خطایی رخ دهد. این از نشت حافظه و مشکلات مربوط به فایل جلوگیری می‌کند.
* **`readLine()`:** یک خط از فایل را به عنوان یک رشته برمی‌گرداند. اگر به انتهای فایل برسد `null` برمی‌گرداند.
* **`IOException`:** یک استثنا است که ممکن است هنگام خواندن فایل رخ دهد. باید آن را مدیریت کنید.

**نکات مهم این روش:**

* **مدیریت استثنا:** حتماً باید بلوک `try-catch` را برای مدیریت استثناها (مانند `FileNotFoundException` یا `IOException`) استفاده کنید.
* **بستن فایل:** بسیار مهم است که فایل را پس از اتمام کار ببندید تا منابع سیستم آزاد شوند. بلوک `try-with-resources` این کار را به صورت خودکار انجام می دهد.
* **مسیر فایل:** اطمینان حاصل کنید که مسیر فایل صحیح است. می‌تواند مسیر مطلق (مانند `C:\Users\YourName\Documents\myfile.txt`) یا مسیر نسبی (نسبت به مکان اجرای برنامه) باشد.

**2. استفاده از `Files.lines()` (Java 8+):**

این روش با استفاده از کلاس `Files` (که از Java 7 معرفی شده) و Stream API (که از Java 8 معرفی شده) راهی تمیزتر و مختصرتر برای خواندن یک فایل متنی ارائه می‌دهد.

```java
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.stream.Stream;

public class ReadFileStream {

public static void main(String[] args) {

String filePath = "path/to/your/file.txt"; // مسیر فایل خود را اینجا قرار دهید

try (Stream lines = Files.lines(Paths.get(filePath))) {

lines.forEach(System.out::println); // چاپ هر خط

// یا می توانید خطوط را به یک لیست تبدیل کنید:
// List lineList = lines.collect(Collectors.toList());

} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
e.printStackTrace();
}
}
}
```

* **`Files.lines(Paths.get(filePath))`:** یک `Stream` از خطوط فایل ایجاد می‌کند. `Paths.get()` یک شی `Path` از مسیر فایل ایجاد می‌کند. با استفاده از `try-with-resources`، استریم به طور خودکار بسته می‌شود.
* **`lines.forEach(System.out::println)`:** از Stream API برای تکرار روی هر خط و چاپ آن استفاده می‌کند. `System.out::println` یک ارجاع متد (method reference) است که به معنی ارسال هر خط به متد `println` در `System.out` است.
* **`lines.collect(Collectors.toList())`:** اگر می خواهید تمام خطوط فایل را در یک لیست ذخیره کنید، می توانید از این خط استفاده کنید.

**مزایای این روش:**

* **کوتاه‌تر و خواناتر:** کد کمتری می‌نویسید.
* **استفاده از Stream API:** امکان استفاده از عملیات stream مانند فیلتر کردن، تبدیل و غیره را فراهم می‌کند.
* **مدیریت خودکار منابع:** استریم به طور خودکار بسته می‌شود.

**3. استفاده از `Scanner`:**

کلاس `Scanner` می‌تواند برای خواندن فایل‌ها با الگوهای مختلف استفاده شود.

```java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadFileScanner {

public static void main(String[] args) {

String filePath = "path/to/your/file.txt"; // مسیر فایل خود را اینجا قرار دهید

try (Scanner scanner = new Scanner(new File(filePath))) {

while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}

} catch (FileNotFoundException e) {
System.err.println("Error: File not found: " + e.getMessage());
e.printStackTrace();
}
}
}
```

* **`Scanner(new File(filePath))`:** یک شی `Scanner` ایجاد می‌کند که فایل را به عنوان ورودی می‌گیرد.
* **`hasNextLine()`:** بررسی می‌کند که آیا خط دیگری در فایل برای خواندن وجود دارد یا خیر.
* **`nextLine()`:** یک خط کامل از فایل را می‌خواند.
* **`FileNotFoundException`:** یک استثنا است که در صورت پیدا نشدن فایل رخ می‌دهد.

**مزایای این روش:**

* **ساده برای خواندن فایل‌های کوچک:** برای خواندن فایل‌های کوچک به سرعت و آسانی قابل استفاده است.
* **توانایی تجزیه:** `Scanner` می‌تواند برای تجزیه داده‌ها از فایل‌ها با الگوهای خاص استفاده شود (به عنوان مثال، خواندن اعداد، کلمات، و غیره).

**معایب این روش:**

* **عملکرد:** می‌تواند برای فایل‌های بزرگ کندتر از `BufferedReader` باشد.
* **مدیریت استثنا:** باید `FileNotFoundException` را به طور خاص مدیریت کنید.

**انتخاب روش مناسب:**

* **فایل‌های بزرگ:** استفاده از `BufferedReader` یا `Files.lines()` توصیه می‌شود.
* **فایل‌های کوچک:** استفاده از `Scanner` می‌تواند سریع و آسان باشد.
* **نیاز به تجزیه داده:** استفاده از `Scanner` مناسب است.
* **Java 8+:** استفاده از `Files.lines()` معمولاً بهترین انتخاب است به دلیل خوانایی و کارایی.

**نکات تکمیلی:**

* **Encoding:** اگر فایل شما از یک encoding خاص (مانند UTF-8) استفاده می‌کند، باید آن را هنگام باز کردن فایل مشخص کنید. برای `FileReader` و `BufferedReader`:

```java
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8"));
```

برای `Files.lines()`:

```java
Stream lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8);
```
* **مسیر فایل:** همیشه از مسیرهای مطلق یا نسبی صحیح استفاده کنید. می‌توانید از `Paths.get(filePath).toAbsolutePath()` برای تبدیل یک مسیر نسبی به یک مسیر مطلق استفاده کنید.
* **اشکال‌زدایی:** اگر هنگام خواندن فایل با مشکل مواجه شدید، مطمئن شوید که فایل وجود دارد، مسیر صحیح است، و برنامه شما مجوز دسترسی به فایل را دارد.

با توجه به نیازهای خود، می‌توانید یکی از این روش‌ها را برای خواندن فایل‌های متنی در جاوا انتخاب کنید. روش `Files.lines()` (به همراه Stream API) اغلب بهترین گزینه برای خوانایی و کارایی است، اما سایر روش‌ها نیز در شرایط خاص ممکن است مناسب باشند.