How can I do to transform from InputStream to FileItem in Java?
Thanks.
Here is a working example. Note that you must change the InputStream from the example with your InputStream, and also you might want to change the location of your work/tmp dir().
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
public class TestFile {
public static void main(String args[]) throws IOException {
// This is a sample inputStream, use your own.
InputStream inputStream = new FileInputStream("c:\\Kit\\Apache\\geronimo-tomcat6-javaee5-2.1.6\\README.txt");
int availableBytes = inputStream.available();
// Write the inputStream to a FileItem
File outFile = new File("c:\\tmp\\newfile.xml"); // This is your tmp file, the code stores the file here in order to avoid storing it in memory
FileItem fileItem = new DiskFileItem("fileUpload", "plain/text", false, "sometext.txt", availableBytes, outFile); // You link FileItem to the tmp outFile
OutputStream outputStream = fileItem.getOutputStream(); // Last step is to get FileItem's output stream, and write your inputStream in it. This is the way to write to your FileItem.
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
// Don't forget to release all the resources when you're done with them, or you may encounter memory/resource leaks.
inputStream.close();
outputStream.flush(); // This actually causes the bytes to be written.
outputStream.close();
// NOTE: You may also want to delete your outFile if you are done with it and dont want to take space on disk.
}
}
Related
I want to calculate the CRC3 checksum of a given InputStream and then use to get the string out of it. Here's what I've tried so far
private long calculateChecksum(InputStream stream) throws IOException {
CRC32 crc = new CRC32();
byte[] buffer = new byte[8192];
int length;
while ((length = stream.read(buffer)) > 0) {
crc.update(buffer, 0, length);
}
return crc.getValue();
}
and then
String text = IOUtils.toString(inputStream, UTF_8);
I also tried to reverse the order. First use it as string and then calculate the checksum. But it didn't work.
What seems to be my issue is that the index goes to the end while calculating the checksum and then doesn't reset. Any idea how to use InputStream after calculating the checksum?
As others said, a stream can be consumed only once. But you can consume it and calculate the CRC value at the same time by wrapping your InputStream with a java.util.zip.CheckedInputStream.
Here is a complete example, assuming the text file "test.txt" is in the current directory and contains only this one line: These are german umlauts: äöüÄÖÜß
import org.apache.commons.io.IOUtils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
public class App {
private static final String INPUT_FILE = "test.txt";
public static void main( String[] args ) {
final CRC32 crc32 = new CRC32();
try(InputStream in = new CheckedInputStream(new BufferedInputStream(
new FileInputStream(INPUT_FILE)), crc32))
{
final String text = IOUtils.toString(in, StandardCharsets.UTF_8);
System.out.println(text);
System.out.println(String.format("CRC32: %x", crc32.getValue()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output:
These are german umlauts: äöüÄÖÜß
CRC32: 84bcd851
Yes, an InputStream is consumed. You have a few options:
mark
mark() / reset() are optional methods of inputstreams; mark sets a mark (this does, by itself, nothing), and reset 'rewinds back' to the mark, replaying everything that was provided since the last time you called mark().
However, your average inputstream either does not support it, or, if it does, supports it by storing in memory all the bytes that are received since setting the mark. Meaning, if you do this to an inputstream that contains a few GB worth of data, you're going to get an OutOfMemoryError.
If there isn't a lot of data, just use mark and reset. Wrap in a BufferedInputStream which is specced to support mark/reset:
private void example(InputStream in) {
BufferedInputStream buffered = new BufferedInputStream(in);
in.mark();
long crc = calculateChecksum(buffered);
in.reset();
String text = IOUtils.toString(buffered, UTF_8);
}
Duplicate
Your second option is to duplicate the inputstream, sending each retrieved byte both to IOUtils as well as to the CRC algorithm.
This is complicated and not recommended.
Checksum the string instead.
You already have a string of data. Just checksum that:
private void example(InputStream in) {
String text = IOUtils.toString(in, UTF_8);
CRC32 crc = new CRC32();
crc.update(text.getBytes(UTF_8));
long checksum = crc.getValue();
}
Or, ditching IOUtils:
private void example(InputStream in) {
byte[] data = in.readAllBytes();
CRC32 crc = new CRC32();
crc.update(data);
long checksum = crc.getValue();
String text = new String(data, UTF_8);
}
InputStream is a read-once stream. Once you've read it, you can't go back to start again. This is because InputStream is general-purpose: it could be the stream of bytes read from a keyboard, for example, or read from a real-time data feed.
If your input stream is in fact a FileInputStream, then you could use
inputStream.getChannel.position(0);
to reset it to the start of the file.
If it's a ByteArrayInputStream, then you already have a byte array so you might as well just use that instead.
If you want to write a general-purpose function that doesn't know what kind of InputStream it is given, then you can wrap it in a BufferedInputStream and use its mark() method. This will use extra memory to buffer the whole of the stream.
I'm new to java and need some understanding on below.
private static void decompressGzipFile(String gzipFile, String newFile) {
try {
FileInputStream fis = new FileInputStream(gzipFile);
GZIPInputStream gis = new GZIPInputStream(fis);
FileOutputStream fos = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];
int len;
while((len = gis.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
//close resources
System.out.println("Decompression is successful");
fos.close();
gis.close();
} catch (IOException e) {
e.printStackTrace();
}
I have some data in compressed GZIP file which is in
í?]o£F ?s?_1RoZ?Öó?¹Ã?d¬ÅÆ[1]?U.?¦Q?8²?Dù÷=?íÄÃÌ ?VUUÎM´d Î?÷|Ì?Í?7ÉöaõÇjûzö³
?9 ??Á¤?? ?? fs?c?;î&Äq?3?Ú?>ÙËv·Ü t¶Y¯w¦uM¿ÿ?Z²?Æò?
________________________________________
[hº~Biþ?F
________________________________________
ÎÁ?bâ??OÃÙ[1]Yã0ó'Q?¬?x?¡ ?â
This is byte data and how can I convert this to string format or readable format in java?
I tried using GZip Uncompressor to read this file but that give me the same file as output but I want the data to be in human readable format. I tried using GZIPInputStream and base64inputStream but that gives incorrect data type. I'm not sure if this is really byte data or how to read this data? any suggestions please help
FileOutputStream bydefault writes data into files using encoding.
If you want to skip encoding , use BufferedReader
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
public class ZipFileReader{
public static void main(String[] args) throws IOException {
GZIPInputStream zipFile = new GZIPInputStream(new FileInputStream("C:/Users/HimanshuSharma2/Downloads/phayes-geoPHP-1.2-20-g6855624.tar.gz"));
BufferedReader br = new BufferedReader(new InputStreamReader(zipFile));
String content;
while ((content = br.readLine()) != null)
System.out.println(content);
}
}
checked on sample file from this link: https://github.com/phayes/geoPHP/tarball/master
and finally write this string into file.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have write a code that transfer file in Java socket but I want to expand it. I want to select the file that I want. And I don't understand one line of code:
byte[] mybytearray = new byte[(int) myFile.length()];
Here's my real code:
import import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
ServerSocket servsock = new ServerSocket(123456);
File myFile = new File("s.pdf");
while (true) {
Socket sock = servsock.accept();
byte[] mybytearray = new byte[(int) myFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
bis.read(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
os.write(mybytearray, 0, mybytearray.length);
os.flush();
sock.close();
}
}
}
The client module:
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class Main {
public static void main(String[] argv) throws Exception {
Socket sock = new Socket("127.0.0.1", 123456);
byte[] mybytearray = new byte[1024];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("s.pdf");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
bos.close();
sock.close();
}
}
That line of code is attempting to make a byte array that has the same size as the file you are reading, allowing it to read the entire file into the byte array in a single read.
The second block of code 'assumes' that the file is no longer than 1024 bytes long, and reads that length maximum, no more. Do you know that the file is <= 1024 bytes long?
For a number of reasons, it is a bad idea to have a variable buffer size when dealing with streams. The beauty of streams is that you don't have the whole file in memory. Instead, use this pattern ... it is easy enough:
{
Socket sock = servsock.accept();
byte[] mybytearray = new byte[4096];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
OutputStream os = sock.getOutputStream();
int amt = bis.read(mybytearray, 0, 4096);
while (amt>0) {
os.write(mybytearray, 0, amt);
amt = bis.read(mybytearray, 0, 4096);
}
os.flush();
sock.close();
}
I chose 4096 as a random arbitrary size, but there is no real reason to choose any size bigger than this. This will copy a file of any size (even gigabytes), the entire file, and it will not cause an out of memory problem when the file gets big.
Have a look at The Java™ Tutorials, Trail: Learning the Java Language, Arrays.
In short: it creates an array for elements of type byte and with a size of the number of bytes in myFile. Since array creation expects an int value for the size and java.io.File offers long length() the returned long value ist cast to (int). Do a DDuckinG and look into the offered tutorials.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
since I dont know how to generate DataInputStream easily, I cant test but pose my questions here. I use Java1.7
I need to manipulate an arrived DataInputStream, skip some bytes, call readShort() several times and skip another bytes. and I wonder:
Q1 if we will lose the original DataInputStream after the skip
Q2 after I call readShort(), would the stream move and point to the next position or it stays at the same position
if you want to skip some bytes you can use
1.readByte() method of DataInputStream and create a for loop of n size to skip n bytes and after that
2.call readShort() method to read short values from the input stream
3.after that again call readByte() to skip again bytes.
feel free to ask your queries
I think I didnt get youre Question fully, but ill provide you 2 Examples, one for
readShort(), which reads two input bytes and returns a short value.
and the
skipBytes(int n) method, which skips over n bytes of data from the
input stream. After skipping you will not be able to read them again
Now you are able to test freely
readShort()
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class DataInputStreamDemo {
public static void main(String[] args) throws IOException {
InputStream is = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
short[] s = {12982,3568};
try{
// create file output stream
fos = new FileOutputStream("c:\\test.txt");
// create data output stream
dos = new DataOutputStream(fos);
// for each short in short buffer
for(short j:s)
{
// write short to data output stream
dos.writeShort(j);
}
// force data to the underlying file output stream
dos.flush();
// create file input stream
is = new FileInputStream("c:\\test.txt");
// create new data input stream
dis = new DataInputStream(is);
// available stream to be read
while(dis.available()>0)
{
// read two bytes from data input, return short
short k = dis.readShort();
// print short value
System.out.print(k+" ");
}
}catch(Exception e){
// if any error occurs
e.printStackTrace();
}finally{
// releases all system resources from the streams
if(is!=null)
is.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
}
}
}
Output: 12982 3568
skipBytes()
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class DataInputStreamDemo {
public static void main(String[] args) throws IOException {
InputStream is = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
byte[] b = {4,124,119,114,125,45,76,83,84};
try{
// create file output stream
fos = new FileOutputStream("c:\\test.txt");
// create data output stream
dos = new DataOutputStream(fos);
// for each byte in buffer
for(byte j:b)
{
// write byte to the output stream
dos.writeByte(j);
}
// force data to the underlying file output stream
dos.flush();
// create file input stream
is = new FileInputStream("c:\\test.txt");
// create new data input stream
dis = new DataInputStream(is);
// available stream to be read
while(dis.available()>0)
{
// reads characters encoded with modified UTF-8
int k = dis.read();
// print
System.out.print(k+" ");
// skips 1 by
dis.skipBytes(1);
}
}catch(Exception e){
// if any error occurs
e.printStackTrace();
}finally{
// releases all system resources from the streams
if(is!=null)
is.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
}
}
}
Output: 4 119 125 76 84
How can I read a short array from a file e.g. audio or video file? And how can I write it back to the file?
I really doubt if SHORT if possible. Nevertheless, you can check out Apache Commons File Utils for reading file as byte[] and vice verse.
public static byte[] readFileToByteArray(File file) throws IOException
This is better example:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
Converting binary data into different forms.
<P>Reads binary data into memory, and writes it back out.
(If your're actually copying a file, there are better ways to do this.)
<P>Buffering is used when reading and writing files, to minimize the number
of interactions with the disk.
*/
public final class BytesStreamsAndFiles {
/** Change these settings before running this class. */
private static final String INPUT_FILE_NAME = "C:\\TEMP\\cottage.jpg";
private static final String OUTPUT_FILE_NAME = "C:\\TEMP\\cottage_copy.jpg";
/** Run the example. */
public static void main(String... aArgs) {
BytesStreamsAndFiles test = new BytesStreamsAndFiles();
//read in the bytes
byte[] fileContents = test.read(INPUT_FILE_NAME);
//test.readAlternateImpl(INPUT_FILE_NAME);
//write it back out to a different file name
test.write(fileContents, OUTPUT_FILE_NAME);
}
/** Read the given binary file, and return its contents as a byte array.*/
byte[] read(String aInputFileName){
log("Reading in binary file named : " + aInputFileName);
File file = new File(aInputFileName);
log("File size: " + file.length());
byte[] result = new byte[(int)file.length()];
try {
InputStream input = null;
try {
int totalBytesRead = 0;
input = new BufferedInputStream(new FileInputStream(file));
while(totalBytesRead < result.length){
int bytesRemaining = result.length - totalBytesRead;
//input.read() returns -1, 0, or more :
int bytesRead = input.read(result, totalBytesRead, bytesRemaining);
if (bytesRead > 0){
totalBytesRead = totalBytesRead + bytesRead;
}
}
/*
the above style is a bit tricky: it places bytes into the 'result' array;
'result' is an output parameter;
the while loop usually has a single iteration only.
*/
log("Num bytes read: " + totalBytesRead);
}
finally {
log("Closing input stream.");
input.close();
}
}
catch (FileNotFoundException ex) {
log("File not found.");
}
catch (IOException ex) {
log(ex);
}
return result;
}
/**
Write a byte array to the given file.
Writing binary data is significantly simpler than reading it.
*/
void write(byte[] aInput, String aOutputFileName){
log("Writing binary file...");
try {
OutputStream output = null;
try {
output = new BufferedOutputStream(new FileOutputStream(aOutputFileName));
output.write(aInput);
}
finally {
output.close();
}
}
catch(FileNotFoundException ex){
log("File not found.");
}
catch(IOException ex){
log(ex);
}
}
/** Read the given binary file, and return its contents as a byte array.*/
byte[] readAlternateImpl(String aInputFileName){
log("Reading in binary file named : " + aInputFileName);
File file = new File(aInputFileName);
log("File size: " + file.length());
byte[] result = null;
try {
InputStream input = new BufferedInputStream(new FileInputStream(file));
result = readAndClose(input);
}
catch (FileNotFoundException ex){
log(ex);
}
return result;
}
/**
Read an input stream, and return it as a byte array.
Sometimes the source of bytes is an input stream instead of a file.
This implementation closes aInput after it's read.
*/
byte[] readAndClose(InputStream aInput){
//carries the data from input to output :
byte[] bucket = new byte[32*1024];
ByteArrayOutputStream result = null;
try {
try {
//Use buffering? No. Buffering avoids costly access to disk or network;
//buffering to an in-memory stream makes no sense.
result = new ByteArrayOutputStream(bucket.length);
int bytesRead = 0;
while(bytesRead != -1){
//aInput.read() returns -1, 0, or more :
bytesRead = aInput.read(bucket);
if(bytesRead > 0){
result.write(bucket, 0, bytesRead);
}
}
}
finally {
aInput.close();
//result.close(); this is a no-operation for ByteArrayOutputStream
}
}
catch (IOException ex){
log(ex);
}
return result.toByteArray();
}
private static void log(Object aThing){
System.out.println(String.valueOf(aThing));
}
}
for more detail go to : Reading and writing binary files
The snippet below reads a file using FileInputStream, and writes the file to the given path using FileOutputStream.
Java Code:
byte[] fileBArray = new byte[(int)file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(fileBArray);
FileOutputStream fos = new FileOutputStream("C:\\abc.jpg");
fos.write(fileBArray);