Determinar o tamanho de um InputStream
-
12-09-2019 - |
Pergunta
A minha situação atual é: eu tenho que ler um arquivo e colocar o conteúdo em InputStream
. Depois que eu preciso para colocar o conteúdo do InputStream
em um array de bytes que requer (tanto quanto eu sei) o tamanho da InputStream
. Alguma idéia?
Conforme solicitado, vou mostrar o fluxo de entrada que eu estou criando a partir de um arquivo enviado
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()
}
}
O pedido é um objeto HttpServletRequest
, que é como o FileItemFactory
e ServletFileUpload
é a partir do pacote Apache Commons FileUpload.
Solução
Eu só queria acrescentar, Apache Commons IO tem utilitários de suporte de fluxo para executar a cópia. (Btw, o que quer dizer, colocando o arquivo em um inputstream? Você pode nos mostrar o seu código?)
Editar:
Ok, o que você quer fazer com o conteúdo do produto?
Há uma item.get()
que retorna a coisa toda em um array de bytes.
Edit2
item.getSize()
voltará a carregado tamanho .
Outras dicas
Esta é uma discussão muito velho, mas ainda era a primeira coisa a aparecer quando eu pesquisei o assunto. Então, eu só queria acrescentar o seguinte:
InputStream inputStream = conn.getInputStream();
int length = inputStream.available();
funcionou para mim. E muito mais simples do que as outras respostas aqui.
Eu leria em um ByteArrayOutputStream e depois chamar ToByteArray () para obter a matriz de bytes resultante. Você não precisa para definir o tamanho de antecedência (embora seja possivelmente uma otimização se você sabe que . Em muitos casos, você não vai)
Você não pode determinar a quantidade de dados em um fluxo sem lê-lo; você pode, no entanto, pedir para o tamanho de um arquivo:
http: // java. sun.com/javase/6/docs/api/java/io/File.html#length ()
Se isso não for possível, você pode escrever os bytes você ler a partir do fluxo de entrada a um ByteArrayOutputStream que vai crescer conforme necessário.
Você pode obter o tamanho do InputStream usando getBytes (inputStream) de Utils.java verificar este seguinte ligação
Para InputStream
org.apache.commons.io.IoUtils.toByteArray(inputStream).length
Para opcional
Stream.of(multipartFile.get()).mapToLong(file->file.getSize()).findFirst().getAsLong()
Quando explicitamente lidar com um ByteArrayInputStream
em seguida, ao contrário de alguns dos comentários nesta página você pode usar a função .available()
para obter o tamanho. Só tenho que fazê-lo antes de começar a ler a partir dele.
A partir dos JavaDocs:
Retorna o número de bytes restantes que podem ser lidos (ou ignorado mais) a partir deste fluxo de entrada. O valor devolvido é Count - pos, que é o número de bytes restantes para ser lido a partir da memória intermédia de entrada.
Se você sabe que seu InputStream
é um FileInputStream
ou um ByteArrayInputStream
, você pode usar um pouco de reflexão para chegar ao tamanho fluxo de sem ler todo o conteúdo . Aqui está um exemplo de método:
static long getInputLength(InputStream inputStream) {
try {
if (inputStream instanceof FilterInputStream) {
FilterInputStream filtered = (FilterInputStream)inputStream;
Field field = FilterInputStream.class.getDeclaredField("in");
field.setAccessible(true);
InputStream internal = (InputStream) field.get(filtered);
return getInputLength(internal);
} else if (inputStream instanceof ByteArrayInputStream) {
ByteArrayInputStream wrapper = (ByteArrayInputStream)inputStream;
Field field = ByteArrayInputStream.class.getDeclaredField("buf");
field.setAccessible(true);
byte[] buffer = (byte[])field.get(wrapper);
return buffer.length;
} else if (inputStream instanceof FileInputStream) {
FileInputStream fileStream = (FileInputStream)inputStream;
return fileStream.getChannel().size();
}
} catch (NoSuchFieldException | IllegalAccessException | IOException exception) {
// Ignore all errors and just return -1.
}
return -1;
}
Esta poderia ser estendido para suportar fluxos de entrada adicionais, tenho a certeza.
Use este método, você só tem que passar o 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: ";
}
try {
InputStream connInputStream = connection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
int size = connInputStream.available();
int disponíveis () Retorna uma estimativa do número de bytes que podem ser lidos (ou saltados por cima) a partir deste fluxo de entrada sem bloquear pelo seguinte invocação de um método para este fluxo de entrada. A próxima invocação pode ser o mesmo segmento ou outro segmento. Uma única leitura ou pular a isso muitas bytes não irá bloquear, mas podem ler ou pule menos bytes.