if I have this code, how could I keep the filename of the original file or reassign it to the new one?:
InputStream input= assetInfo.openStream();
File t = new File("");
OutputStream out = new FileOutputStream(t);
int read=0;
byte[] bytes = new byte[1024];
while((read = input.read(bytes))!= -1){
out.write(bytes, 0, read);
}
An input stream can be created to read from a file or from any other source of data. Therefore it makes no sense to have a filename attached to an input stream. Look in assetInfo to see if that class exposes that data (you can even look inside the class using reflection). Note that the creator or assetInfo made a design mistake not exposing this information, OR you are trying to make one now.
Related
//Reading a image file from #drawable res folder and writing to a file on external sd card
//below one works no doubt but I want to imrpove it:
OutputStream os = new FileOutputStream(file); //File file.........
InputStream is =getResources().openRawResource(R.drawable.an_image);
byte[] b = new byte[is.available()];
is.read(b);
os.write(b);
is.close();
os.close();
In above code I am using basic io classes to read and write. My question is what can I do in order to able to use wrapper classes like say DataInputStream/ BufferedReaderd or PrintStream / BufferedWriter /PrintWriter.
As openRawResources(int id ) returns InputStream ;
to read a file from res I either need to typecast like this:
DataInputStream is = (DataInputStream) getResources().openRawResource(R.drawble.an_image));
or I can link the stream directly like this:
DataInputStream is = new DataInputStream(getResources().openRawResource(R.drawable.greenball));
and then I may do this to write it to a file on sd card:
PrintStream ps =new PrintStream (new FileOutputStream(file));
while(s=is.readLine()!=null){
ps.print(s);
}
So is that correct approach ? which one is better? Is there a better way?better practice..convention?
Thanks!!!
If openRawResource() is documented to return an InputStream then you cannot rely on that result to be any more specific kind of InputStream, and in particular, you cannot rely on it to be a DataInputStream. Casting does not change that; it just gives you the chance to experience interesting and exciting exceptions. If you want a DataInputStream wrapping the the result of openRawResource() then you must obtain it via the DataInputStream constructor. Similarly for any other wrapper stream.
HOWEVER, do note that DataInputStream likely is not the class you want. It is appropriate for reading back data that were originally written via a DataOutputStream, but it is inappropriate (or at least offers no advantages over any other InputStream) for reading general data.
Furthermore, your use of InputStream.available() is incorrect. That method returns the number of bytes that can currently be read from the stream without blocking, which has only a weak relationship with the total number of bytes that could be read from the stream before it is exhausted (if indeed it ever is).
Moreover, your code is also on shaky ground where it assumes that InputStream.read(byte[]) will read enough bytes to fill the array. It probably will, since that many bytes were reported available, but that's not guaranteed. To copy from one stream to another, you should instead use code along these lines:
private final static int BUFFER_SIZE = 2048;
void copyStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int nread;
while ( (nread = in.read(buffer) != 0 ) do {
out.write(buffer, 0, nread);
}
}
I am receiving an InputStream from HttpUrlConnection (connection.getInputStream()), and I am parsing the input stream using DocumentBuilder (documenbtBuilder.parse(inputStream)). Before parsing, I want to write the received data to log file. When I do that, I get org.xml.sax.SAXParseException: Unexpected end of document Exception in the parse method. My code works fine if I don't write to file, but I need to log the data received.
Please find the code that writes to file below :
final InputStream input = connection.getInputStream();
writeLogInfo(input);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
//Method that writes tito log file.
private void writeLogInfo(InputStream input){
OutputStream os = new FileOutputStream("mylogfile.txt");
byte[] buffer = new byte[1024];
int byteRead;
while((byteRead = input.read(buffer)) != -1){
os.write(buffer,0,byteRead);
}
os.flush();
os.close();
}
I suspect it is because of multiple use of InputStream, since the code works when I don't invode writeLogInfo(). I am not closing the inputstream anywhere in my code. What am I doing wrong here ?
When you are writing the content to a file, you are reaching the end of the inputstream.
So after that, when you are trying to parse, you get the exception.
You need to use mark and reset methods on the inputstream before passing it to documentbuilder.
Also, first you need to check if the input stream supports mark.
Here is the javadoc, for your reference
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html
Are you sure the size of the file is under 1024 bytes. If not why don't you put your "inputstream" to BufferredInputstream, and create the byte array..
BufferedInputStream bin= new BufferedInputStream(new DataInputStream(input));
byte[] buffer= new byte[bin.available()];
bin.read(buffer);
os.write(buffer);
......
......
bin.close();
......
I know that there are some similar questions in the site, but they could not provide me a helpful answer. What is the best/most efficient way to read a .bin file in Java line by line? Which classes and methods should someone use to open it and get the data? Could Bufferedreader do the job or is it only for text files;
Binary file don't have lines, but you must know the format of the file to know what structure exists (headers, structs,etc) and write a parser.
You can use BufferedInputStream, see the following:
http://www.javapractices.com/topic/TopicAction.do?Id=245
Read structured data from binary file -?
This should do it.
public byte[] readFromStream(InputStream inputStream) throws Exception
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
byte[] data = new byte[4096];
int count = inputStream.read(data);
while(count != -1)
{
dos.write(data, 0, count);
count = inputStream.read(data);
}
return baos.toByteArray();
}
I am having an application where two processes talk using SOAP. A file is being transferred from Process A to Process B. Where Process B will store it to DB.
opqData.setBase64Binary(new DataHandler(new FileDataSource(file)));
where file is the data which needs to be stored to the DB.
However now i want to zip the data when storing it to DB. One option is to zip the file and send it as FileDataSource. However i cant use it because we have more than 1000 such files and it creates a lot of zip entries in the file structure and creating the zip is additions overhead.
So i was thinking to implement the DataHandler as GzipDataHandler and the input stream returned is gzipInputStream to process B. So the data will be zipped and stored to the DB.
However i am confused how to write the getInputStream method for my new GzipDataHandler.
Has any one tried something like this before? Or can i get any pointers from Java and SOAP experts?
Thanks,
Dheeraj Joshi
This might help you:
http://www.exampledepot.com/egs/java.util.zip/CompressFile.html
Ok. I found out the solution.
Solution is not to change the DataHandler but to change the FileDataSource.
Create a new FileDataSource say ZipFileDataSource and extend the FileDataSource and implement the getInputStream method.
Your getInputStream method should read the file and GZIPOutputStream should zip it and it should be passed through the pipes to the caller.
final PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos);
FileInputStream fis = null;
GZIPOutputStream gos = null;
byte[] buffer = new byte[1024];
try {
fis = new FileInputStream(MyFile);
gos = new GZIPOutputStream(pos);
int length;
while ((length = fis.read(buffer, 0, 1024)) != -1)
gos.write(buffer, 0, length);
fis.close();
} catch(Exception e){
}
Above is the sample code.
Regards,
Dheeraj Joshi
I have some working code in python that I need to convert to Java.
I have read quite a few threads on this forum but could not find an answer. I am reading in a JPG image and converting it into a byte array. I then write this buffer it to a different file. When I compare the written files from both Java and python code, the bytes at the end do not match. Please let me know if you have a suggestion. I need to use the byte array to pack the image into a message that needs to be sent over to a remote server.
Java code (Running on Android)
Reading the file:
File queryImg = new File(ImagePath);
int imageLen = (int)queryImg.length();
byte [] imgData = new byte[imageLen];
FileInputStream fis = new FileInputStream(queryImg);
fis.read(imgData);
Writing the file:
FileOutputStream f = new FileOutputStream(new File("/sdcard/output.raw"));
f.write(imgData);
f.flush();
f.close();
Thanks!
InputStream.read is not guaranteed to read any particular number of bytes and may read less than you asked it to. It returns the actual number read so you can have a loop that keeps track of progress:
public void pump(InputStream in, OutputStream out, int size) {
byte[] buffer = new byte[4096]; // Or whatever constant you feel like using
int done = 0;
while (done < size) {
int read = in.read(buffer);
if (read == -1) {
throw new IOException("Something went horribly wrong");
}
out.write(buffer, 0, read);
done += read;
}
// Maybe put cleanup code in here if you like, e.g. in.close, out.flush, out.close
}
I believe Apache Commons IO has classes for doing this kind of stuff so you don't need to write it yourself.
Your file length might be more than int can hold and than you end up having wrong array length, hence not reading entire file into the buffer.