I am trying to transfer a .mp4 file using WebRTC and it's DataChannel. In order to do that I am breaking the file into chunks like below:
FileInputStream is = new FileInputStream(file);
byte[] chunk = new byte[260000];
int chunkLen = 0;
sentFileByte = new ArrayList<>();
while ((chunkLen = is.read(chunk)) != -1) {
sentFileByte.add(chunk);
}
After that, sending the chunks by index like:
byte[] b = sentFileByte.get(index);
ByteBuffer bb = ByteBuffer.wrap(b);
bb.put(b);
bb.flip();
dataChannel.send(new DataChannel.Buffer(bb, true));
On the receiver end I am receiving the chunks and adding it to an Arraylist
receivedFileByteArr.add(chunkByteArr);
After receiving all the chunks successfully I am trying to convert these in to a file like below:
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/" + fileName;
File file = new File(path);
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int i = 0; i < receivedFileByteArr.size(); i++) {
fileOutputStream.write(receivedFileByteArr.get(i));
}
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
After completing all these steps, file is created successfully. File size is also same. But problem is the file is not playable in any video player. I guess I am making some mistake on FileInputStream and FileOutputStream. I need help to fix this error.
With Java:
I have a byte[] that represents a file.
How do I write this to a file (ie. C:\myfile.pdf)
I know it's done with InputStream, but I can't seem to work it out.
Use Apache Commons IO
FileUtils.writeByteArrayToFile(new File("pathname"), myByteArray)
Or, if you insist on making work for yourself...
try (FileOutputStream fos = new FileOutputStream("pathname")) {
fos.write(myByteArray);
//fos.close(); There is no more need for this line since you had created the instance of "fos" inside the try. And this will automatically close the OutputStream
}
Without any libraries:
try (FileOutputStream stream = new FileOutputStream(path)) {
stream.write(bytes);
}
With Google Guava:
Files.write(bytes, new File(path));
With Apache Commons:
FileUtils.writeByteArrayToFile(new File(path), bytes);
All of these strategies require that you catch an IOException at some point too.
Another solution using java.nio.file:
byte[] bytes = ...;
Path path = Paths.get("C:\\myfile.pdf");
Files.write(path, bytes);
Also since Java 7, one line with java.nio.file.Files:
Files.write(new File(filePath).toPath(), data);
Where data is your byte[] and filePath is a String. You can also add multiple file open options with the StandardOpenOptions class. Add throws or surround with try/catch.
From Java 7 onward you can use the try-with-resources statement to avoid leaking resources and make your code easier to read. More on that here.
To write your byteArray to a file you would do:
try (FileOutputStream fos = new FileOutputStream("fullPathToFile")) {
fos.write(byteArray);
} catch (IOException ioe) {
ioe.printStackTrace();
}
Try an OutputStream or more specifically FileOutputStream
Basic example:
String fileName = "file.test";
BufferedOutputStream bs = null;
try {
FileOutputStream fs = new FileOutputStream(new File(fileName));
bs = new BufferedOutputStream(fs);
bs.write(byte_array);
bs.close();
bs = null;
} catch (Exception e) {
e.printStackTrace()
}
if (bs != null) try { bs.close(); } catch (Exception e) {}
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
////////////////////////// 1] File to Byte [] ///////////////////
Path path = Paths.get(p);
byte[] data = null;
try {
data = Files.readAllBytes(path);
} catch (IOException ex) {
Logger.getLogger(Agent1.class.getName()).log(Level.SEVERE, null, ex);
}
/////////////////////// 2] Byte [] to File ///////////////////////////
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
I know it's done with InputStream
Actually, you'd be writing to a file output...
This is a program where we are reading and printing array of bytes offset and length using String Builder and Writing the array of bytes offset length to the new file.
`Enter code here
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//*This is a program where we are reading and printing array of bytes offset and length using StringBuilder and Writing the array of bytes offset length to the new file*//
public class ReadandWriteAByte {
public void readandWriteBytesToFile(){
File file = new File("count.char"); //(abcdefghijk)
File bfile = new File("bytefile.txt");//(New File)
byte[] b;
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream (file);
fos = new FileOutputStream (bfile);
b = new byte [1024];
int i;
StringBuilder sb = new StringBuilder();
while ((i = fis.read(b))!=-1){
sb.append(new String(b,5,5));
fos.write(b, 2, 5);
}
System.out.println(sb.toString());
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fis != null);
fis.close(); //This helps to close the stream
}catch (IOException e){
e.printStackTrace();
}
}
}
public static void main (String args[]){
ReadandWriteAByte rb = new ReadandWriteAByte();
rb.readandWriteBytesToFile();
}
}
O/P in console : fghij
O/P in new file :cdefg
You can try Cactoos:
new LengthOf(new TeeInput(array, new File("a.txt"))).value();
More details: http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html
This question already has answers here:
Convert InputStream to byte array in Java
(34 answers)
Closed 4 years ago.
I am trying to convert an InputStream into a byte array to write it in a file, to generate a PDF.
I have a File type with the url of a PDF, and with that, i have the inputStream of that.
File fichero_pdf = new File("C:/Users/agp2/Desktop/PDF_TRIAXE.pdf");
InputStream stream4 = new FileInputStream(fichero_pdf);
Until here everything is perfect, the problem appears when i try to transform this InputStream to a byte[] and write it in a new File.
I have these two methods:
to convert the Stream to a byte[]:
private static byte[] getArrayFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString().getBytes();
}
To write the byte[] in the new file:
...
File file=new File(dto.getTitulo());
InputStream stream=dto.getContenido();
byte[] array=getStringFromInputStream(stream);
OutputStream salida=new FileOutputStream(file);
salida.write(array);
salida.close();
stream.close();
helper.addAttachment(file.getName(), file);
}
mailSender.send(message);
...
The Email is sent at perfection, but when i can't open the .pdf.
Also, i compare the code of the new pdf with the code of the first, and is a little bit different.
I need to create a valid pdf file from an inputStream.
You have 2 problems:
You are trying to read bytes as strings, but you don't have to do it. In your case you should use byte streams(FileInputStream, BufferedInputStream), not char streams(InputStreamReader, BufferedReader).
You loose data when you convert String to bytes here:
return sb.toString().getBytes();
I would like to suggest you to use java 7 try-with-resources instead of try-catch-finally.
You can read the whole file to a byte array using ByteArrayOutputStream.
Sample code does the following:
getArrayFromInputStream() - reads all file bytes to byte array
writeContent() - writes content to a new file, in my example pdf_sample2.pdf
Example:
public class ReadAllBytes {
// as example - write to resources folder
private static String DIR = "src\\main\\resources\\";
public static void main(String[] args) throws IOException {
try {
byte[] fileAsBytes = getArrayFromInputStream(new FileInputStream(new File(DIR + "pdf-sample.pdf")));
writeContent(fileAsBytes, DIR + "pdf_sample2.pdf");
} catch (Exception e){
e.printStackTrace();
}
}
private static byte[] getArrayFromInputStream(InputStream inputStream) throws IOException {
byte[] bytes;
byte[] buffer = new byte[1024];
try(BufferedInputStream is = new BufferedInputStream(inputStream)){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int length;
while ((length = is.read(buffer)) > -1 ) {
bos.write(buffer, 0, length);
}
bos.flush();
bytes = bos.toByteArray();
}
return bytes;
}
private static void writeContent(byte[] content, String fileToWriteTo) throws IOException {
File file = new File(fileToWriteTo);
try(BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(file))){
salida.write(content);
salida.flush();
}
}
}
I'm trying to write compressed data to a file and then read in the data and decompress it using the GZIP library. I've tried changing all formatting to StandardCharsets.UTF-8 and ISO-8859-1 and neither have fixed the GZIP format error. I'm wondering if it could possible have to do with the file I'm reading in? Here's the compression function:
public static byte[] compress(String originalFile, String compressFile) throws IOException {
// read in data from text file
// The name of the file to open.
String fileName = originalFile;
// This will reference one line at a time
String line = null;
String original = "";
try {
// FileReader reads text files in the default encoding.
FileReader fileReader =
new FileReader(fileName);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader =
new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null) {
original.concat(line);
}
// Always close files.
bufferedReader.close();
}
catch(FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
fileName + "'");
}
catch(IOException ex) {
System.out.println(
"Error reading file '"
+ fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}
// create a new output stream for original string
try (ByteArrayOutputStream out = new ByteArrayOutputStream())
{
try (GZIPOutputStream gzip = new GZIPOutputStream(out))
{
gzip.write(original.getBytes(StandardCharsets.UTF_8));
}
byte[] compressed = out.toByteArray();
out.close();
String compressedFileName = compressFile;
try {
// Assume default encoding.
FileWriter fileWriter =
new FileWriter(compressedFileName);
// Always wrap FileWriter in BufferedWriter.
BufferedWriter bufferedWriter =
new BufferedWriter(fileWriter);
// Note that write() does not automatically
// append a newline character.
String compressedStr = compressed.toString();
bufferedWriter.write(compressedStr);
// Always close files.
bufferedWriter.close();
}
catch(IOException ex) {
System.out.println(
"Error writing to file '"
+ fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}
return compressed;
}
}
(I'm receiving the error on the line in the following decompression function) -
GZIPInputStream compressedByteArrayStream = new GZIPInputStream(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)));
Decompression Function:
public static String decompress(String file) throws IOException {
byte[] compressed = {};
String s = "";
File fileName = new File(file);
FileInputStream fin = null;
try {
// create FileInputStream object
fin = new FileInputStream(fileName);
// Reads up to certain bytes of data from this input stream into an array of bytes.
fin.read(compressed);
//create string from byte array
s = new String(compressed);
System.out.println("File content: " + s);
}
catch (FileNotFoundException e) {
System.out.println("File not found" + e);
}
catch (IOException ioe) {
System.out.println("Exception while reading file " + ioe);
}
finally {
// close the streams using close method
try {
if (fin != null) {
fin.close();
}
}
catch (IOException ioe) {
System.out.println("Error while closing stream: " + ioe);
}
}
// create a new input string for compressed byte array
GZIPInputStream compressedByteArrayStream = new GZIPInputStream(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)));
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
// create a string builder and byte reader for the compressed byte array
BufferedReader decompressionBr = new BufferedReader(new InputStreamReader(compressedByteArrayStream, StandardCharsets.UTF_8));
StringBuilder decompressionSb = new StringBuilder();
// write data to decompressed string
String line1;
while((line1 = decompressionBr.readLine()) != null) {
decompressionSb.append(line1);
}
decompressionBr.close();
int len;
String uncompressedStr = "";
while((len = compressedByteArrayStream.read(buffer)) > 0) {
uncompressedStr = byteOutput.toString();
}
compressedByteArrayStream.close();
return uncompressedStr;
}
Here's the error message that i am receiving:
[B#7852e922
File content:
java.io.EOFException
at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:268)
at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:258)
at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:164)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
at org.kingswoodoxford.Compression.decompress(Compression.java:136)
at org.kingswoodoxford.Compression.main(Compression.java:183)
Any suggestions as to how I might be able to fix this?
When you read the file you discard the new line at the end of each line.
A more efficient option which does do this is to copy a block i.e. char[] at a time. You can also convert the text as you go rather than creating a String or a byte[].
BTW original.concat(line); returns the concatenated string which you are discarding.
The real problem is you write to one stream and close a different one. This means that if there is any buffered data at the end of the file (and this is highly likely) the end of the file will be truncated and when you read it it will complain that your file is incomplete or EOFException.
Here is a shorter example
public static void compress(String originalFile, String compressFile) throws IOException {
char[] buffer = new char[8192];
try (
FileReader reader = new FileReader(originalFile);
Writer writer = new OutputStreamWriter(
new GZIPOutputStream(new FileOutputStream(compressFile)));
) {
for (int len; (len = reader.read(buffer)) > 0; )
writer.write(buffer, 0, len);
}
}
In the decompress, don't encode binary as text and attempt to get back the same data. It will almost certainly be corrupted. Try to use a buffer and a loop like I did for compress. i.e. it shouldn't be any more complicated.
//Or any other solution to saving multipartfile into DB.
I tried with this way but getting error.
File fileOne = new File("file.getOrignalFileName");//what should be kept inside this method
byte[] bFile = new byte[(int) fileOne.length()];
try {
FileInputStream fileInputStream = new FileInputStream(fileOne);
//convert file into array of bytes
fileInputStream.read(bFile);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
questionDao.saveImage(bFile);
MultipartFile file;
byte [] byteArr=file.getBytes();
InputStream inputStream = new ByteArrayInputStream(byteArr);
//Start Photo Upload with Adhaar No//
if (simpleLoanDto.getPic() != null && simpleLoanDto.getAdharNo() != null) {
String ServerDirPath = globalVeriables.getAPath() + "\\";
File ServerDir = new File(ServerDirPath);
if (!ServerDir.exists()) {
ServerDir.mkdirs();
}
// Giving File operation permission for LINUX//
IOperation.setFileFolderPermission(ServerDirPath);
MultipartFile originalPic = simpleLoanDto.getPic();
byte[] ImageInByte = originalPic.getBytes();
FileOutputStream fosFor = new FileOutputStream(
new File(ServerDirPath + "\\" + simpleLoanDto.getAdharNo() + "_"+simpleLoanDto.getApplicantName()+"_.jpg"));
fosFor.write(ImageInByte);
fosFor.close();
}
//End Photo Upload with Adhaar No//