2013-04-23 39 views
5

Được tìm kiếm trong một thời gian ngắn và tôi hơi bối rối về vấn đề này. Tôi muốn có thể tham gia luồng đầu vào và đọc đồng thời trong các phân đoạn. Các phân đoạn không tương tác với nhau, chúng chỉ là giá trị được chèn vào hoặc cập nhật trong cơ sở dữ liệu từ tệp được tải lên. Có thể đọc luồng đầu vào đồng thời bằng cách đặt kích thước phân đoạn và sau đó chỉ bỏ qua trước khi quay ra một chuỗi mới để xử lý chuyển đổi và chèn/cập nhật?Java: Đồng thời đọc trên InputStream

Về cơ bản tệp là danh sách ID (một ID trên mỗi dòng), mặc dù nó sẽ là thích hợp hơn nếu tôi có thể chỉ định dấu phân cách. Một số tệp có thể rất lớn vì vậy tôi muốn xử lý và chuyển đổi dữ liệu thành các phân đoạn để sau khi chèn/cập nhật cơ sở dữ liệu, bộ nhớ JVM có thể được giải phóng. Điều này có thể không? Và nếu có thì có thư viện nào ở đó đã làm điều này chưa?

Chúc mừng và cảm ơn trước,

Alexei Blue.

Trả lời

6

Một cách tiếp cận tốt có thể thay vì để có một đầu đọc duy nhất đọc khối và sau đó đưa từng đoạn ra một chuỗi công nhân từ một nhóm luồng. Cho rằng chúng sẽ được chèn vào một cơ sở dữ liệu, các phần chèn sẽ là các phần chậm so với việc đọc đầu vào sao cho một luồng duy nhất đủ để đọc.

Dưới đây là ví dụ cho phép xử lý từng dòng từ System.in đến chuỗi công nhân. Hiệu năng chèn cơ sở dữ liệu tốt hơn nhiều nếu bạn thực hiện chèn số lượng lớn trong một giao dịch duy nhất để chuyển một nhóm gồm 1000 dòng sẽ tốt hơn so với truyền trong một dòng như trong ví dụ.

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Main { 
    public static class Worker implements Runnable { 
     private final String line; 

     public Worker(String line) { 
      this.line = line; 
     } 

     @Override 
     public void run() { 
      // Process line here. 
      System.out.println("Processing line: " + line); 
     } 
    } 

    public static void main(String[] args) throws IOException { 
     // Create worker thread pool. 
     ExecutorService service = Executors.newFixedThreadPool(4); 

     BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); 
     String line; 

     // Read each line and hand it off to a worker thread for processing. 
     while ((line = buffer.readLine()) != null) { 
      service.execute(new Worker(line)); 
     } 
    } 
} 
+0

Hi Ed cảm ơn ví dụ ^.^Vì vậy, nếu tôi đọc 1000 dòng vào một StringBuffer và sau đó vượt qua này để một sợi công nhân được xử lý và chèn/cập nhật trong cơ sở dữ liệu bạn có nghĩ rằng đây sẽ là một cách tiếp cận tốt? :) –

+0

Nó có lẽ là tốt nhất để đọc 1000 dòng vào một 'Danh sách ' hoặc một 'Chuỗi []'. Nếu bạn đọc chúng thành một 'StringBuffer' thì nó sẽ là một chuỗi duy nhất và bạn cần phân tích các dòng riêng lẻ lần thứ hai. –

1

Tôi không nghĩ rằng bạn có thể đọc đồng thời InputStream. Đó là lý do tại sao hợp đồng xác định đọc, đặt lại và đánh dấu - ý tưởng là luồng theo dõi nội bộ những gì đã được đọc và những gì không có.

Nếu bạn đang đọc tệp, chỉ cần mở nhiều luồng. Bạn có thể sử dụng phương thức skip() để di chuyển điểm đánh dấu phía trước cho các chuỗi khác để tránh xử lý dòng trùng lặp. BufferedReader cũng có thể giúp một số vì nó cung cấp đọc số line by line.

+0

Yeah bộ đệm đệm + bỏ qua là cách tôi hiện đang làm, cần một chút công việc hơn nhưng tôi chắc chắn bằng cách sử dụng một tuần tự đọc và di chuyển công việc cho các chủ đề khác sẽ là một cải tiến tốt. Chúc mừng cho các liên kết. –

1

Trước hết, để đọc tệp đồng thời bắt đầu từ các chênh lệch khác nhau, bạn cần truy cập ngẫu nhiên vào tệp, điều này có nghĩa là đọc tệp từ bất kỳ vị trí nào. Java cho phép điều này với RandomAccessFile trong java.in hoặc với SeekableByteChannel trong java.nio:

Best Way to Write Bytes in the Middle of a File in Java

http://docs.oracle.com/javase/tutorial/essential/io/rafs.html

Tôi nghĩ rằng vì những lý do tốc độ bạn sẽ thích java.nio. Java NIO FileChannel versus FileOutputstream performance/usefulness

Bây giờ bạn biết cách đọc từ bất kỳ vị trí nào nhưng bạn cần thực hiện đồng thời. Không thể với cùng một đối tượng truy cập tệp vì chúng giữ vị trí trong tệp. Vì vậy, bạn cần nhiều đối tượng truy cập tệp dưới dạng chủ đề. Vì bạn đang đọc không viết nên được Ok.

Bây giờ bạn biết cách đọc cùng một tệp đồng thời từ nhiều lần đặt khác nhau.

Nhưng hãy nghĩ về hiệu suất.Mặc dù số lượng các chủ đề bạn chỉ có MỘT ổ đĩa và đọc ngẫu nhiên (nhiều chủ đề truy cập cùng một tập tin) hiệu suất là chậm hơn nhiều nhiều sau đó tuần tự đọc (một chủ đề đọc một tập tin). Ngay cả khi nó tấn công 0 hoặc 1 - không quan trọng. Đọc tuần tự luôn nhanh hơn nhiều. Vì vậy, trong trường hợp của bạn tôi sẽ khuyên bạn nên đọc các tập tin trong một sợi và cung cấp các chủ đề khác với các dữ liệu từ đó đọc thread.

+0

Chúc mừng Vitaly và cảm ơn các liên kết –

Các vấn đề liên quan