2009-07-13 47 views
39

Tình trạng hiện tại của tôi là: Tôi phải đọc tệp và đưa nội dung vào InputStream. Sau đó, tôi cần đặt nội dung của InputStream vào một mảng byte yêu cầu (theo như tôi biết) kích thước của InputStream. Bất kỳ ý tưởng?Xác định kích thước của InputStream

Theo yêu cầu, tôi sẽ hiển thị các dòng đầu vào mà tôi đang tạo ra từ một tập tin được tải lên

InputStream uploadedStream = null; 
FileItemFactory factory = new DiskFileItemFactory(); 
ServletFileUpload upload = new ServletFileUpload(factory); 
java.util.List items = upload.parseRequest(request);  
java.util.Iterator iter = items.iterator(); 

while (iter.hasNext()) { 
    FileItem item = (FileItem) iter.next(); 
    if (!item.isFormField()) { 
     uploadedStream = item.getInputStream(); 
     //CHANGE uploadedStreambyte = item.get() 
    } 
} 

Yêu cầu là một đối tượng HttpServletRequest, mà cũng giống như FileItemFactoryServletFileUpload là từ gói Apache Commons FileUpload.

Trả lời

10

Tôi chỉ muốn thêm, Apache Commons IO có dòng hỗ trợ tiện ích để thực hiện sao chép. (Btw, những gì bạn có nghĩa là bằng cách đặt các tập tin vào một inputstream bạn có thể chỉ cho chúng tôi mã của bạn?)

Edit:

Được rồi, những gì bạn muốn làm gì với nội dung của các mục? Có một item.get()which returns toàn bộ nội dung trong một mảng byte.

Edit2

item.getSize() sẽ trả lại tải lên file size.

+0

Tôi hiện đang lưu tệp vào trường blob trong cơ sở dữ liệu và tôi gửi nó dưới dạng nhị phân (đầu vào làm đầu vào), bây giờ tôi yêu cầu inputstream trong mảng byte vì tôi cần tạo chữ ký dữ liệu và hàm chỉ mất mảng byte. – ChronoXIII

+1

item.get() lưới bạn mảng byte, như tôi đã đề cập. Và đừng lo lắng về hiệu suất một kích thước trừ khi bạn đang làm việc với một số hình ảnh MB. – akarnokd

+0

Đó có thể là trường hợp do hình ảnh được tải lên bởi người dùng và tôi dường như không thể tìm cách tự động cắt hình ảnh ở phía máy chủ. :( – ChronoXIII

16

Bạn không thể xác định lượng dữ liệu trong luồng mà không đọc; bạn có thể, tuy nhiên, yêu cầu kích thước của một tập tin:

http://java.sun.com/javase/6/docs/api/java/io/File.html#length()

Nếu điều đó là không thể, bạn có thể viết các byte bạn đọc từ dòng đầu vào cho một ByteArrayOutputStream mà sẽ phát triển theo yêu cầu.

+0

Trong kịch bản của tôi inputstream chứa một tập tin được tải lên từ một dạng HTML, tôi không thể có được kích thước tập tin kể từ khi tôi đang không tải các tập tin ra khỏi ổ đĩa cứng. – ChronoXIII

+1

Nếu luồng đầu vào của bạn có hỗ trợ mark(), bạn có thể đánh dấu ở đầu và chỉ đọc toàn bộ luồng đó - sau đó đặt lại() và bắt đầu xử lý nó. – akarnokd

+1

tệp là hình ảnh (có khả năng lớn) để đọc qua luồng hai lần sẽ gây ra sự cố hiệu suất phải không? – ChronoXIII

24

Tôi sẽ đọc một số ByteArrayOutputStream và sau đó gọi toByteArray() để nhận mảng byte kết quả. Bạn không cần phải xác định kích thước trước (mặc dù nó có thể là một tối ưu hóa nếu bạn biết nó. Trong nhiều trường hợp bạn sẽ không)

+0

Tôi dường như đã tìm thấy rằng inputstream có một toString() phương pháp và sau đó tôi chỉ có thể gọi một getBytes() để tạo ra một mảng byte ra khỏi chuỗi. Tôi tự hỏi nếu có bất kỳ vấn đề hiệu suất từ ​​làm điều này? – ChronoXIII

+0

Bạn cần phải cẩn thận với các chuyển đổi byte/ký tự. Đây có phải là một luồng byte không? Nếu nó chứa các ký tự, chúng được mã hóa như thế nào. Nếu bạn nhận được thông qua kết nối mạng, tôi nghi ngờ đó là nút cổ chai hiệu suất chính của bạn và tôi sẽ không lo lắng về chi phí chuyển đổi –

+0

. cơ sở dữ liệu như một dòng nhị phân, điều này dường như làm việc tốt như tôi có thể đọc các tập tin trở lại afterwords và nó vẫn là một hình ảnh – ChronoXIII

3

bạn có thể nhận được kích thước của InputStream sử dụng getBytes (InputStream) của Utils.java kiểm tra liên kết này sau

Get Bytes from Inputstream

+0

. Câu trả lời chính xác? Bất kỳ vấn đề với giải pháp này? – Arlyn

27

Đây là một chủ đề REALLY cũ, nhưng nó vẫn là điều đầu tiên bật lên khi tôi googled vấn đề. Vì vậy, tôi chỉ muốn thêm điều này:

InputStream inputStream = conn.getInputStream(); 
int length = inputStream.available(); 

Làm việc cho tôi. Và MUCH đơn giản hơn các câu trả lời khác ở đây.

+38

Tôi không nghĩ đó là chính xác. Từ Javadocs: "Lưu ý rằng trong khi một số triển khai của InputStream sẽ trả về tổng số byte trong luồng, nhiều người sẽ không sử dụng giá trị trả về của phương thức này để cấp phát bộ đệm nhằm chứa tất cả dữ liệu trong suối." Vì vậy, nó có thể đã làm việc trên máy ảo của bạn, nhưng có thể không hoạt động trên người khác. http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available() – Marvo

+3

Oh psych. Đẹp bắt! Tôi đoán mẹo này không tốt cho mã cần phải di chuyển. Tôi đã sử dụng cho một dự án trường học, vì vậy nó đã làm việc cho tôi. Cảm ơn mặc dù, tốt để biết cho tương lai! –

+4

Điều đó hoàn hảo khi bạn có tất cả dữ liệu trong bộ nhớ như trong ByteArrayInputStream. – stacker

-1

Sử dụng phương pháp này, bạn chỉ cần có để vượt qua InputStream

public String readIt(InputStream is) { 
    if (is != null) { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8); 

     StringBuilder sb = new StringBuilder(); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line).append("\n"); 
     } 
     is.close(); 
     return sb.toString(); 
    } 
    return "error: "; 
} 
+1

-1, điều này giả định 'InputStream' luôn là Chuỗi (không phải cần thiết vì nó có thể là dữ liệu nhị phân) và trong mọi trường hợp, nó không trả về kích thước của luồng mà câu hỏi được yêu cầu. Hơn nữa, nó bổ sung thêm các byte ('\ n') vào dữ liệu để' sb.length() 'cũng sẽ không chính xác. –

+0

Ok, tôi hiểu, vì vậy điều này rất hữu ích khi bạn biết bạn đang mong nhận được luồng 'Chuỗi'. '\ n' thực sự cần thiết vì bạn phải cung cấp một số định dạng cho đầu vào nhận được, tôi không muốn một chuỗi dài' Chuỗi', vì vậy ngay cả những '\ n'giá. –

0

Khi rõ ràng đối phó với một ByteArrayInputStream sau đó trái với một số ý kiến ​​trên trang này bạn có thể sử dụng chức năng .available() để có được kích thước. Chỉ cần làm điều đó trước khi bạn bắt đầu đọc từ nó.

Từ JavaDocs:

Trả về số byte còn lại có thể được đọc (hoặc bỏ qua trở lên) từ input stream này. Giá trị trả về là đếm - pos, trong đó là số byte còn lại sẽ được đọc từ bộ đệm đầu vào.

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html#available()

0
try { 
     InputStream connInputStream = connection.getInputStream(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    int size = connInputStream.available(); 

int sẵn() Trả ước tính số byte có thể được đọc (hoặc bỏ qua) từ input stream này mà không chặn bởi gọi tiếp theo của một phương pháp để luồng đầu vào này. Lệnh gọi tiếp theo có thể là cùng một luồng hoặc một luồng khác. Một lần đọc hoặc bỏ qua nhiều byte này sẽ không chặn, nhưng có thể đọc hoặc bỏ qua ít byte hơn.

InputStream - Android SDK | Android Developers

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