2009-03-06 13 views
11

Học Java, vì vậy hãy nhẹ nhàng làm ơn. Lý tưởng nhất là tôi cần phải tạo một mảng các byte sẽ trỏ đến một phần của một mảng lớn hơn:Trong Java: là nơi mà một cách để tạo một subarray sẽ trỏ đến một phần của một mảng lớn hơn?

byte[] big = new byte[1000]; 

// C-style code starts 
load(file,big); 

byte[100] sub = big + 200; 

// C-style code ends 

Tôi biết điều này là không thể trong Java và có hai vấn đề cần lưu ý và sẽ bao gồm:

  1. Hoặc phần sao chép lớn vào phụ iterating qua lớn.

  2. Hoặc writting lớp riêng mà sẽ mất một tham chiếu đến lớn + bù đắp + kích thước và thực hiện "subarray" thông qua phương pháp accessor sử dụng lớn như cấu trúc dữ liệu cơ bản thực tế.

Tác vụ tôi đang cố giải quyết là tải tệp vào bộ nhớ, sau đó truy cập chỉ đọc vào các bản ghi được lưu trữ với tệp thông qua lớp. Tốc độ là tối quan trọng, do đó lý tưởng tôi muốn tránh sao chép hoặc phương pháp accessor. Và kể từ khi tôi đang học Java, tôi muốn gắn bó với nó.

Bất kỳ lựa chọn thay thế nào khác mà tôi có? Vui lòng đặt câu hỏi nếu tôi không giải thích đủ về công việc.

+0

Không nhất quán: byte [] sub = new byte [100]; dự trữ không gian cho 100 byte nhưng phân bổ phụ = lớn + 200; chỉ lưu trữ một con trỏ. –

+0

sganslandt, đúng vậy. Đã chuyển sang mã kiểu C. –

Trả lời

21

Tạo mảng dưới dạng "chế độ xem" của một mảng khác không thể thực hiện được trong Java. Nhưng bạn có thể sử dụng java.nio.ByteBuffer, về cơ bản là lớp bạn đề xuất trong bài tập # 2. Ví dụ:

ByteBuffer subBuf = ByteBuffer.wrap(big, 200, 100).slice().asReadOnlyBuffer(); 

Không sao chép (một số tạo đối tượng). Là một lớp thư viện chuẩn, tôi cũng giả định rằng ByteBuffer có nhiều khả năng nhận được xử lý đặc biệt hơn.Tối ưu hóa "JIT" của JVM so với tùy chỉnh.

1

Hãy xem mã nguồn của java.lang.String (nó sẽ nằm trong src.zip hoặc src.jar). Bạn sẽ thấy rằng họ có một mảng của cahrs và sau đó là một bắt đầu và kết thúc. Vì vậy, có, giải pháp là sử dụng một lớp học để làm điều đó.

Here is a link to the source online.

Các biến đáng chú ý là:

  • giá trị
  • bù đắp
  • đếm

chuỗi con có lẽ là một phương pháp tốt để xem xét như là một điểm khởi đầu.

Nếu bạn muốn đọc directlry từ tệp sử dụng lớp java.nio.channels.FileChannel, cụ thể là phương thức map() - cho phép bạn sử dụng I/O bộ nhớ được ánh xạ rất nhanh và sử dụng ít bộ nhớ hơn quá trình sao chép mảng.

+0

Hãy nhớ việc triển khai chuỗi trong khi đọc một tệp lớn: các phương thức phân tách và chuỗi con giữ tham chiếu đến chuỗi gốc. Vì vậy, nếu bạn đọc một tập tin 1 GB, và lưu trữ chỉ là từ đầu tiên của mỗi dòng, nhu cầu không gian vẫn còn 1 GB !!! – pihentagy

3

Nếu bạn muốn đọc tệp nhanh và có quyền truy cập ở mức độ thấp, hãy kiểm tra nội dung java nio. Dưới đây là ví dụ từ java almanac.

Bạn có thể sử dụng bộ đệm byte được ánh xạ để điều hướng bên trong nội dung tệp.

+0

Cảm ơn Miguel, nhưng có vẻ như dưới mui xe giải pháp này không có 1 và không có 2 kết hợp. –

0

Đọc tệp vào bộ nhớ là tệp tin tốt về sớm sẽ tương đối nhỏ. Nhưng khi bạn phải đối phó với các tập tin lớn giữ chúng ra khỏi bộ nhớ là một mục tiêu mong muốn hơn nhiều.

MappedByteBuffer là thứ bạn đang tìm kiếm.

MappedByteBuffer là bộ đệm byte trực tiếp có nội dung là vùng được ánh xạ bộ nhớ của tệp. Nội dung của bộ đệm byte được ánh xạ có thể thay đổi bất kỳ lúc nào, ví dụ: nếu nội dung của vùng tương ứng của tệp được ánh xạ bị thay đổi bởi chương trình này hoặc chương trình khác. Có hay không những thay đổi như vậy xảy ra, và khi chúng xảy ra, là hệ điều hành phụ thuộc và do đó không xác định.

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