BufferedInputStream into byte[] to be send over a Socket to a Database
Have a look at ByteArrayOutputStream: Java 7 API java.io.ByteArrayOutputStream
bytesOut = new ByteArrayOutputStream();
byte[] bytes = bytesOut.toByteArray();
Update: If you insist on doing what you are doing you can just assign the intermediate ByteArrayOutputStream to a variable and get hold of the array that way:
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream()
BufferedOutputStream out = new BufferedOutputStream(bytesOut);
copy(in, out);
return bytesOut.toByteArray();
Update 2: The real question seems to be how to copy a file without reading it all into memory first:
1) Manually:
byte[] buff = new byte[64*1024]; //or some size, can try out different sizes for performance
BufferedInputStream in = new BufferedInputStream(new FileInputStream("fromFile"));
BufferedOutputStream out = new BufferedOutputStream(new FileoutputStream("toFile"));
int n = 0;
while ((n = in.read(buff)) >= 0) {
out.write(buff, 0, n);
}
in.close();
out.close();
2) Efficiently by the OS and no loop etc:
FileChannel from = new FileInputStream(sourceFile).getChannel();
FileChanngel to = new FileOutputStream(destFile).getChannel();
to.transferFrom(from, 0, from.size());
//or from.transferTo(0, from.size(), to);
from.close();
to.close();
3) If you have Java 7 you can simplify exception and stream closing or just copy the file with the new APIs i in java 7:
java.nio.file.Files.copy(...);
OmniOwl
Software Developer, Indie Game Developer & Architect of Play
Updated on January 19, 2020Comments
-
OmniOwl over 4 years
I have been looking around for an answer to this, but couldn't really find anything on it. Earlier today, I asked how I could make a File into a String through a byte array, and then back again, for retrieval later.
What people told me, was that I had to just store the byte array, to avoid nasty encoding issues. So now I've started working on that, but I have now hit a wall.
Basically, I used unbuffered streams before, to turn a file into a byte array. This works good in theory, but it takes up a lot of memory which eventually will cast the heap size exception. I should use buffered streams instead (or so I am told), and the problem I have now, is going from a BufferedInputStream to a byte[]. I've tried to copy and use the methods found in this documentation
Where I exchange unbuffered streams for buffered streams. The only issue, is that I can't directly turn a buffered output stream into a byte array, as I can with an unbuffered stream.
Help? :)
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public final class BufferedByteStream { private static final int BUF_SIZE = 1024000; public static long copy(BufferedInputStream from, BufferedOutputStream to) throws IOException { byte[] buf = new byte[BUF_SIZE]; long total = 0; while(true) { int r = from.read(buf); if(r == -1) { break; } to.write(buf, 0, r); total += r; } return total; } public static byte[] toByteArray(BufferedInputStream in) throws IOException { BufferedOutputStream out = new BufferedOutputStream(new ByteArrayOutputStream()); copy(in, out); return out. // <--- Problem is here } }
EDIT:
I am still getting Heap Space errors. So I will now post all the code:
main.java
import java.io.*; import java.util.logging.Level; import java.util.logging.Logger; import jserver.io.BufferedByteStream; /** * * @author Vipar */ public class main { public static void main(String[] args) { File f = new File("<doesn't matter>"); try { byte[] buf; try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f))) { buf = BufferedByteStream.toByteArray(bis); bis.close(); } File f2 = new File("<doesn't matter>"); try (FileOutputStream fos = new FileOutputStream(f2)) { fos.write(buf); fos.close(); } } catch (FileNotFoundException ex) { Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex); } } }
BufferedByteStream.java
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public final class BufferedByteStream { private static final int BUF_SIZE = 1024000; public static long copy(BufferedInputStream from, BufferedOutputStream to) throws IOException { byte[] buf = new byte[BUF_SIZE]; long total = 0; while(true) { int r = from.read(buf); if(r == -1) { break; } to.write(buf, 0, r); total += r; } return total; } public static byte[] toByteArray(BufferedInputStream in) throws IOException { ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); BufferedOutputStream out = new BufferedOutputStream(bytesOut); copy(in, out); return bytesOut.toByteArray(); } }
-
Mattias Isegran Bergander almost 12 yearsYou don't need any more buffering... It's building an array in memory. It doesn't get more buffered than that.
-
Mattias Isegran Bergander almost 12 yearsHowever if you don't belieive me (you should measure yourself anyway), you can just use it anyway but assign it to it's own variable in between. I'll update the example.
-
OmniOwl almost 12 yearsI tried to make a copy of 1.39 GB file on my computer through unbuffered streams. It gave me the "run out of memory" exception. I was told buffered streams, could be a solution to this.
-
Mattias Isegran Bergander almost 12 yearsI think you or the other party misunderstood if so, that won't help.
-
Mattias Isegran Bergander almost 12 yearsWhat you need is to not read all of it into memory first and then write it, just write it as you go. Meaning, don't use ByteArray streams.
-
Mattias Isegran Bergander almost 12 yearsIf all you want is to copy a file, either do it manually: read a chunk of bytes from a FileInputStream wrapped in a BufferedInputStream and write a chunk to a FileOutputSteream wrapped in a BufferedOutputStream or let the OS do it more efficiently if it is able to using
transferTo()
-
OmniOwl almost 12 yearsIt's not JUST a matter of copying the file. It's supposed to be used in a web solution, kind of, where a client can send this to a server, but it's made into a byte array, before it's sent. I am still getting heap space errors, so I will update my main post.
-
Rick Mangi almost 12 yearsYou might want to look at ByteBuffer instead.
-
Mattias Isegran Bergander almost 12 yearsIf it is stored as a byte array inbetween it is stored in memory, and will take up 1,39GB in memory... so storing it in a byte array sounds really bad if you need any decent sized files I'm afraid.
-
OmniOwl almost 12 yearsI posted all the code I got. I suppose I will rewrite the topics name too. Just in case.
-
Mattias Isegran Bergander almost 12 yearsThat code internally stores the bytes in an array for no good reason though? If that is what it is doing you can as well go with either the updated answer solution 1) or upcoming 2)