As the title suggests, is there any way to read a binary representation of a given file (.txt, .docx, .exe, etc...) in Java (or any other language)?
In java, I know how to read the content of a file as is, i.e:
String line;
BufferedReader br = new BufferedReader(new FileReader("myFile.txt"));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
But I'm not sure (if it's possible) to read a binary representation of the file itself.
File file = new File(filePath);
byte[] bytes = new byte[(int)file.length()];
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
dataInputStream.readFully(bytes);
dataInputStream.close();
bytes is a byte array with all of the data of the file in it
Related
I write some file transfer application. Between client and server i send 3 type of data:
1) Some "command words" like READY_FOR_UPLOAD.
2) Some serializable data
3) Big files in byte array.
I get client connections on server socket and create new Thread for every client.
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
InputStream inputStream = clientSocket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {}
I create these streams using try with resources and there is no problem.
I use:
1) "in" for read messages from client:
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
2)"out" for send messages.
3)"inputStream" for receive files:
try (FileOutputStream fileOutputStream = new
FileOutputStream("D:\\testDownload.zip");
BufferedOutputStream bufferedOutputStream = new
BufferedOutputStream(fileOutputStream)
) {
byte[] buffer = new byte[1024 * 100];
int read;
while ((read = inputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, read);
}
}
4) "objectInputStream" for serializable data:
Object object;
if ((object = objectInputStream.readObject()) != null) {
if (object instanceof File) {
File file = (File) object;
System.out.println(file.getAbsolutePath());
System.out.println(file.length());
}
}
While i use them separately - there is no problem. But i need read "command word" first of all i.e. in start of the method run of my tread.
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
InputStream inputStream = clientSocket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
String line;
if ((line = in.readLine()) != null) {
System.out.println(line);
there i should try to read other types of data
}
}
And if this is no "command word" i can try read serializable data or file data. But this is a problem! I may try to read a line but it can be part of serializable data of file data and because inputsream readed "one-by-one" byte method, i can't try read it like serializable or file data, because input not whole anymore, i read some data in "readLine()". I should know what type of data i receive before i try to read it. How can it be done?
You need to create a protocol - rules how client and server exchange information between them.
When you write data you specify what data type you are sending and its size. And don't use ObjectInputStream and ObjectOutputStream on Socket - convert the data into array of bytes, so that you know what the size is when you writing and then convert them back. Send the data as bytes.
I want download only first 3 bytes of file from web, but can't do that.
This method download all file
BufferedReader r = new BufferedReader(new InputStreamReader(imageStream), 3);
as I get InputStream class always download all file..
BufferedReaderis handy if you are trying to read characters.
For example:
char[] charBuff = new charBuff[n];
new BufferedReader(new InputStreamReader(stream)).read(charBuff,0,n);
This Wii read n bytes from the input stream and will store them in the char array.
If you just want to read bytes and store them in a byte array try using this:
byte[] byteBuff= new byteBuff[n];
new BufferedInputStream(input stream).read(byteBuff,0,n);
connection.setRequestProperty("Range", "bytes="+0+"-"+2);
connection.connect();
BufferedReader r = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder total = new StringBuilder();
String line;
line = r.readLine();
Log.i(LOG_TAG, line);
am trying to read a JSON response using buffered reader as shown below. I'm using Apache Commons Http client. Response comes as a single line JSON and no of characters are around 1060000 and size is approximately 1 MB. Problem am facing is only part of stream is read by reader and other part is missing. How can i read the full JSON without losing any data.? Is this related to 'CharBufferSize' of BufferedReader or no of characters in the stream ?
InputStream stream = method.getResponseBodyAsStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
try using a json parser.
import org.codehaus.jackson.*;
JsonFactory fac = new JsonFactory();
JsonParser parser = fac .createJsonParser(stream);
If you just want to copy the complete stream into the StringBuilder, you should use the InputStreamReader and a char-array buffer.
InputStream stream = method.getResponseBodyAsStream();
InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
StringBuilder builder = new StringBuilder();
char[] buffer = new char[4096];
int read;
while ((read = reader.read(buffer)) != -1) {
builder.append(buffer, 0, read);
}
Finally i was able to solve using the IOUtils in Apache Commons library. Here is the code.
BoundedInputStream boundedInputStream= new BoundedInputStream(stream);
BufferedReader reader = new BufferedReader(new InputStreamReader(boundedInputStream,"UTF-8"));
StringBuilder builder= new StringBuilder();
StringBuilderWriter writer = new StringBuilderWriter(builder);
IOUtils.copy(reader, writer);
Although it is been a while, it may be helpful for someone.
Here is the original source,
Most Robust way of reading a file or stream using Java (To prevent DoS attacks)
I have a client that uploads a vcf file, and I get this file at server side and reads it contents and saves them to a txt file. But there is a character error when I try read it, if there is turkish characters it looks like "?". My read code is here:
FileItemStream item = null;
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterator = upload.getItemIterator(request);
String encoding = null;
while (iterator.hasNext()) {
item = iterator.next();
if ("fileUpload".equals(item.getFieldName())) {
InputStreamReader isr = new InputStreamReader(item.openStream(), "UTF-8");
String str = "";
String temp="";
BufferedReader br = new BufferedReader(isr);
while((temp=br.readLine()) != null){
str +=temp;
}
br.close();
File f = new File("C:/sedat.txt");
BufferedWriter buf = new BufferedWriter(new FileWriter(f));
buf.write(str);
buf.close();
}
BufferedWriter buf = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
If this is production code, i would recommend writing the output straight to the file and not accumulating it in the string first. And, you could avoid any potential encoding issues by reading the source as an InputStream and writing as an OutputStream (and skipping the conversion to characters).
What's the difference between using a BufferedReader and a BufferedInputStream?
A BufferedReader is used for reading character data. A BufferedOutputStream is used for writing binary data.
Any classes inheriting from Reader or Writer deal with 16-bit unicode character data, whereas classes inherting from InputStream or OutputStream are concerned with processing binary data. The classes InputStreamReader and OutputStreamWriter can be used to bridge between the two classes of data.
Bufferedreader reads data from a file as a string. BufferedOutputStream writes to a file in bytes. BufferedInputStream reads data in bytes
Sample to Bufferedreader:
try {
BufferedReader br = new BufferedReader(new FileReader(new File(your_file));
while ((thisLine = br.readLine()) != null) {
System.out.println(thisLine);
}
}
Sample to BufferedOutputStream:
//Construct the BufferedOutputStream object
bufferedOutput = new BufferedOutputStream(new FileOutputStream(filename));
//Start writing to the output stream
bufferedOutput.write("Line 1".getBytes());
bufferedOutput.write("\r\n".getBytes());
bufferedOutput.write("Line 2".getBytes());
bufferedOutput.write("\r\n".getBytes());
Bufferedinputstream reads in byte:
Sample
:
//Construct the BufferedInputStream object
bufferedInput = new BufferedInputStream(new FileInputStream(filename));
int bytesRead = 0;
while ((bytesRead = bufferedInput.read(buffer)) != -1) {
String chunk = new String(buffer, 0, bytesRead);
System.out.print(chunk);
}
As the names imply, one is for reading data, and the other is for outputting data.