Java - Tệp và I / O

Gói java.io chứa gần như mọi lớp mà bạn có thể cần để thực hiện nhập và xuất (I / O) trong Java. Tất cả các luồng này đại diện cho một nguồn đầu vào và một điểm đến đầu ra. Luồng trong gói java.io hỗ trợ nhiều dữ liệu như nguyên thủy, đối tượng, ký tự được bản địa hóa, v.v.

Suối

Luồng có thể được định nghĩa là một chuỗi dữ liệu. Có hai loại Luồng -

  • InPutStream - InputStream được sử dụng để đọc dữ liệu từ một nguồn.

  • OutPutStream - OutputStream được sử dụng để ghi dữ liệu đến một đích.

Java cung cấp hỗ trợ mạnh mẽ nhưng linh hoạt cho I / O liên quan đến tệp và mạng nhưng hướng dẫn này bao gồm chức năng rất cơ bản liên quan đến luồng và I / O. Chúng ta sẽ lần lượt xem các ví dụ thường được sử dụng nhất -

Luồng Byte

Các luồng byte Java được sử dụng để thực hiện đầu vào và đầu ra của các byte 8 bit. Mặc dù có nhiều lớp liên quan đến luồng byte nhưng các lớp được sử dụng thường xuyên nhất là,FileInputStreamFileOutputStream. Sau đây là một ví dụ sử dụng hai lớp này để sao chép tệp đầu vào thành tệp đầu ra:

Example

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {  
      FileInputStream in = null;
      FileOutputStream out = null;

      try {
         in = new FileInputStream("input.txt");
         out = new FileOutputStream("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

Bây giờ chúng ta hãy có một tệp input.txt với nội dung sau -

This is test for copy file.

Bước tiếp theo, hãy biên dịch chương trình trên và thực thi nó, điều này sẽ dẫn đến việc tạo tệp output.txt với nội dung giống như chúng ta có trong input.txt. Vì vậy, hãy đặt đoạn mã trên vào tệp CopyFile.java và thực hiện như sau:

$javac CopyFile.java
$java CopyFile

Luồng nhân vật

Java Byte luồng được sử dụng để thực hiện đầu vào và đầu ra của byte 8 bit, trong khi Java Charactercác luồng được sử dụng để thực hiện nhập và xuất cho unicode 16-bit. Mặc dù có nhiều lớp liên quan đến luồng ký tự nhưng các lớp được sử dụng thường xuyên nhất là,FileReaderFileWriter. Mặc dù bên trong FileReader sử dụng FileInputStream và FileWriter sử dụng FileOutputStream nhưng ở đây sự khác biệt chính là FileReader đọc hai byte một lúc và FileWriter ghi hai byte một lúc.

Chúng ta có thể viết lại ví dụ trên, sử dụng hai lớp này để sao chép tệp đầu vào (có các ký tự unicode) vào tệp đầu ra -

Example

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {
      FileReader in = null;
      FileWriter out = null;

      try {
         in = new FileReader("input.txt");
         out = new FileWriter("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

Bây giờ chúng ta hãy có một tệp input.txt với nội dung sau -

This is test for copy file.

Bước tiếp theo, hãy biên dịch chương trình trên và thực thi nó, điều này sẽ dẫn đến việc tạo tệp output.txt với nội dung giống như chúng ta có trong input.txt. Vì vậy, hãy đặt đoạn mã trên vào tệp CopyFile.java và thực hiện như sau:

$javac CopyFile.java
$java CopyFile

Luồng chuẩn

Tất cả các ngôn ngữ lập trình đều cung cấp hỗ trợ cho I / O tiêu chuẩn, nơi chương trình của người dùng có thể nhận đầu vào từ bàn phím và sau đó tạo ra kết quả trên màn hình máy tính. Nếu bạn biết đến ngôn ngữ lập trình C hoặc C ++, thì bạn phải biết đến ba thiết bị tiêu chuẩn STDIN, STDOUT và STDERR. Tương tự, Java cung cấp ba luồng tiêu chuẩn sau:

  • Standard Input - Điều này được sử dụng để cung cấp dữ liệu cho chương trình của người dùng và thường bàn phím được sử dụng làm luồng nhập chuẩn và được biểu diễn dưới dạng System.in.

  • Standard Output - Điều này được sử dụng để xuất dữ liệu do chương trình của người dùng tạo ra và thông thường màn hình máy tính được sử dụng cho luồng đầu ra tiêu chuẩn và được biểu diễn dưới dạng System.out.

  • Standard Error - Điều này được sử dụng để xuất ra dữ liệu lỗi do chương trình của người dùng tạo ra và thông thường màn hình máy tính được sử dụng cho luồng lỗi tiêu chuẩn và được biểu diễn dưới dạng System.err.

Sau đây là một chương trình đơn giản, tạo ra InputStreamReader để đọc luồng đầu vào chuẩn cho đến khi người dùng nhập "q" -

Example

import java.io.*;
public class ReadConsole {

   public static void main(String args[]) throws IOException {
      InputStreamReader cin = null;

      try {
         cin = new InputStreamReader(System.in);
         System.out.println("Enter characters, 'q' to quit.");
         char c;
         do {
            c = (char) cin.read();
            System.out.print(c);
         } while(c != 'q');
      }finally {
         if (cin != null) {
            cin.close();
         }
      }
   }
}

Hãy giữ đoạn mã trên trong tệp ReadConsole.java và cố gắng biên dịch và thực thi nó như được hiển thị trong chương trình sau. Chương trình này tiếp tục đọc và xuất cùng một ký tự cho đến khi chúng ta nhấn 'q' -

$javac ReadConsole.java
$java ReadConsole
Enter characters, 'q' to quit.
1
1
e
e
q
q

Đọc và ghi tệp

Như đã mô tả trước đó, một luồng có thể được định nghĩa là một chuỗi dữ liệu. CácInputStream được sử dụng để đọc dữ liệu từ một nguồn và OutputStream được sử dụng để ghi dữ liệu đến một đích.

Đây là một hệ thống phân cấp các lớp để xử lý các luồng Đầu vào và Đầu ra.

Hai luồng quan trọng là FileInputStreamFileOutputStream, sẽ được thảo luận trong hướng dẫn này.

FileInputStream

Luồng này được sử dụng để đọc dữ liệu từ các tệp. Các đối tượng có thể được tạo bằng từ khóanew và có một số loại hàm tạo có sẵn.

Hàm khởi tạo sau lấy tên tệp làm chuỗi để tạo đối tượng luồng đầu vào để đọc tệp:

InputStream f = new FileInputStream("C:/java/hello");

Hàm tạo sau lấy một đối tượng tệp để tạo một đối tượng luồng đầu vào để đọc tệp. Đầu tiên, chúng ta tạo một đối tượng tệp bằng phương thức File () như sau:

File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);

Khi bạn đã có đối tượng InputStream trong tay, thì sẽ có một danh sách các phương thức trợ giúp có thể được sử dụng để đọc luồng hoặc thực hiện các thao tác khác trên luồng.

Sr.No. Phương pháp & Mô tả
1

public void close() throws IOException{}

Phương thức này đóng luồng xuất tệp. Giải phóng mọi tài nguyên hệ thống được liên kết với tệp. Ném IOException.

2

protected void finalize()throws IOException {}

Phương pháp này xóa kết nối với tệp. Đảm bảo rằng phương thức đóng của luồng xuất tệp này được gọi khi không còn tham chiếu nào đến luồng này. Ném IOException.

3

public int read(int r)throws IOException{}

Phương thức này đọc byte dữ liệu được chỉ định từ InputStream. Trả về một số nguyên. Trả về byte dữ liệu tiếp theo và -1 sẽ được trả về nếu đó là phần cuối của tệp.

4

public int read(byte[] r) throws IOException{}

Phương thức này đọc byte r.length từ luồng đầu vào vào một mảng. Trả về tổng số byte đã đọc. Nếu nó là phần cuối của tệp, -1 sẽ được trả về.

5

public int available() throws IOException{}

Cung cấp số byte có thể đọc được từ luồng nhập tệp này. Trả về một số nguyên.

Có sẵn các luồng đầu vào quan trọng khác, để biết thêm chi tiết, bạn có thể tham khảo các liên kết sau:

  • ByteArrayInputStream

  • DataInputStream

FileOutputStream

FileOutputStream được sử dụng để tạo một tệp và ghi dữ liệu vào đó. Luồng sẽ tạo một tệp, nếu nó chưa tồn tại, trước khi mở nó để xuất.

Đây là hai hàm tạo có thể được sử dụng để tạo một đối tượng FileOutputStream.

Hàm tạo sau lấy tên tệp làm chuỗi để tạo đối tượng luồng đầu vào để ghi tệp:

OutputStream f = new FileOutputStream("C:/java/hello")

Hàm tạo sau lấy một đối tượng tệp để tạo một đối tượng luồng đầu ra để ghi tệp. Đầu tiên, chúng ta tạo một đối tượng tệp bằng phương thức File () như sau:

File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

Khi bạn đã có đối tượng OutputStream trong tay, thì sẽ có một danh sách các phương thức trợ giúp, có thể được sử dụng để ghi vào luồng hoặc để thực hiện các thao tác khác trên luồng.

Sr.No. Phương pháp & Mô tả
1

public void close() throws IOException{}

Phương thức này đóng luồng xuất tệp. Giải phóng mọi tài nguyên hệ thống được liên kết với tệp. Ném IOException.

2

protected void finalize()throws IOException {}

Phương pháp này xóa kết nối với tệp. Đảm bảo rằng phương thức đóng của luồng xuất tệp này được gọi khi không còn tham chiếu nào đến luồng này. Ném IOException.

3

public void write(int w)throws IOException{}

Phương thức này ghi byte được chỉ định vào luồng đầu ra.

4

public void write(byte[] w)

Ghi các byte w.length từ mảng byte được đề cập đến OutputStream.

Có sẵn các luồng đầu ra quan trọng khác, để biết thêm chi tiết, bạn có thể tham khảo các liên kết sau:

  • ByteArrayOutputStream

  • DataOutputStream

Example

Sau đây là ví dụ để chứng minh InputStream và OutputStream:

import java.io.*;
public class fileStreamTest {

   public static void main(String args[]) {
   
      try {
         byte bWrite [] = {11,21,3,40,5};
         OutputStream os = new FileOutputStream("test.txt");
         for(int x = 0; x < bWrite.length ; x++) {
            os.write( bWrite[x] );   // writes the bytes
         }
         os.close();
     
         InputStream is = new FileInputStream("test.txt");
         int size = is.available();

         for(int i = 0; i < size; i++) {
            System.out.print((char)is.read() + "  ");
         }
         is.close();
      } catch (IOException e) {
         System.out.print("Exception");
      }	
   }
}

Đoạn mã trên sẽ tạo tệp test.txt và sẽ ghi các số nhất định ở định dạng nhị phân. Tương tự sẽ là kết quả trên màn hình stdout.

Điều hướng tệp và I / O

Có một số lớp học khác mà chúng ta sẽ trải qua để tìm hiểu những điều cơ bản về Điều hướng tệp và I / O.

  • Lớp tệp

  • Lớp FileReader

  • Lớp FileWriter

Thư mục trong Java

Thư mục là một Tệp có thể chứa danh sách các tệp và thư mục khác. Bạn dùngFileđối tượng để tạo thư mục, liệt kê các tệp có sẵn trong một thư mục. Để biết chi tiết đầy đủ, hãy kiểm tra danh sách tất cả các phương thức mà bạn có thể gọi trên đối tượng Tệp và những gì liên quan đến thư mục.

Tạo thư mục

Có hai hữu ích File các phương thức tiện ích, có thể được sử dụng để tạo thư mục -

  • Các mkdir( )phương thức tạo một thư mục, trả về true khi thành công và false khi thất bại. Lỗi chỉ ra rằng đường dẫn được chỉ định trong đối tượng Tệp đã tồn tại hoặc không thể tạo thư mục vì toàn bộ đường dẫn chưa tồn tại.

  • Các mkdirs() phương thức này tạo cả một thư mục và tất cả các thư mục cha của thư mục.

Ví dụ sau tạo thư mục "/ tmp / user / java / bin" -

Example

import java.io.File;
public class CreateDir {

   public static void main(String args[]) {
      String dirname = "/tmp/user/java/bin";
      File d = new File(dirname);
      
      // Create directory now.
      d.mkdirs();
   }
}

Biên dịch và thực thi đoạn mã trên để tạo "/ tmp / user / java / bin".

Note- Java tự động xử lý các dấu phân cách đường dẫn trên UNIX và Windows theo quy ước. Nếu bạn sử dụng dấu gạch chéo (/) trên phiên bản Windows của Java, đường dẫn sẽ vẫn phân giải chính xác.

Danh sách thư mục

Bạn có thể dùng list( ) phương pháp được cung cấp bởi File để liệt kê tất cả các tệp và thư mục có sẵn trong một thư mục như sau:

Example

import java.io.File;
public class ReadDir {

   public static void main(String[] args) {
      File file = null;
      String[] paths;
  
      try {      
         // create new file object
         file = new File("/tmp");

         // array of files and directory
         paths = file.list();

         // for each name in the path array
         for(String path:paths) {
            // prints filename and directory name
            System.out.println(path);
         }
      } catch (Exception e) {
         // if any error occurs
         e.printStackTrace();
      }
   }
}

Điều này sẽ tạo ra kết quả sau dựa trên các thư mục và tệp có sẵn trong /tmp thư mục -

Output

test1.txt
test2.txt
ReadDir.java
ReadDir.class