I'm trying to read a date (set of 6 integers) and temperature (double) from binary .dat file.
After multiple tries I finally got to the stage where the file is working, but it's returning int in the format I cannot recognize. Eg. date 2017-03-02 11:33 , and temperature 3.8 is read as:
Measure : 515840-1024-1024 2816 8512 241591910
temperature: 1.9034657819129845E185
Any ideas, how to change the code?
public void readFile() {
try {
DataInputStream dis = null;
BufferedInputStream bis = null;
try {
FileInputStream fis = new FileInputStream(fileLocation);
int b;
bis = new BufferedInputStream(fis);
dis = new DataInputStream(fis);
while ((b = dis.read()) != -1) {
System.out.println("Measure : " + dis.readInt() + "-"
+ dis.readInt() + "-" + dis.readInt() + " " +
dis.readInt() + " " + dis.readInt() + " "
+ dis.readInt() + " Temperature: "+ dis.readDouble());
}
} finally {
dis.close();
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (EOFException f) {
f.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} // readFile
while ((b = dis.read()) != -1) {
The problem is here. This reads and discards a byte of the file on every iteration, so all subsequent reads are out of sync.
The correct way to loop with a DataInputStream or ObjectInputStream is with a while (true) loop, and terminating it when read() returns -1, readLine() returns null, or readXXX() for any other X throws EOFException.
Note that you don't normally need to log or print a stack trace on EOFException, as it's a normal loop termination condition ... unless you had reason to expect more data, e.g. your file started with a record count that you haven't reached yet, which might indicate that the file was truncated and therefore corrupt.
Related
I'm a noob to Java so may be missing something obvious but I have a function which works for files files in the 200-300k range without issue but once I get to 1.4mb it falls over silently!
Here's the code:
private String readOutputFile(String filename) {
if (filename == null) {
return null;
}
File file = new File(filename);
FileInputStream fis = null;
String fileContent = "";
this.logger.log("Reading " + filename + " from filesystem.");
try {
fis = new FileInputStream(file);
System.out.println("Total file size to read (in bytes) : " + fis.available());
int content;
while ((content = fis.read()) != -1) {
fileContent += (char) content;
}
} catch (IOException e) {
this.logger.log("IO Problem reading ITMS output file\n");
e.printStackTrace();
throw new Error("io-error/itms-output");
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
this.logger.log("IO Problem reading and/or closing ITMS output file\n");
ex.printStackTrace();
throw new Error("io-error/finally-block");
}
}
this.logger.log("File content has been read in");
String compressed = this.compress(this.cleanXML(fileContent));
this.logger.log("The compressed file size is :" + compressed.length() + " bytes");
return compressed;
}
When it hits the size threshold which creates it to fail, it seems to stay within the while loop or at least that's my assumption because while it does report to the console the "Total file size to read ..." it never reaches the "File content has been read in" logging.
You are creating many temporary String objects by performing character concatenation in your loop. I would use a StringBuilder. I would also prefer a try-with-resources. And if at all possible, I would prefer to stream from the InputStream to the OutputStream directly (instead of reading this entirely into memory). Anyway, based on what is here,
private String readOutputFile(String filename) {
if (filename == null) {
return null;
}
File file = new File(filename);
StringBuilder sb = new StringBuilder();
this.logger.log("Reading " + filename + " from filesystem.");
try (FileInputStream fis = new FileInputStream(file)) {
System.out.println("Total file size to read (in bytes) : " + fis.available());
int content;
while ((content = fis.read()) != -1) {
sb.append((char) content);
}
} catch (IOException e) {
this.logger.log("IO Problem reading ITMS output file\n");
e.printStackTrace();
throw new Error("io-error/itms-output");
}
this.logger.log("File content has been read in");
String compressed = this.compress(this.cleanXML(sb.toString()));
this.logger.log("The compressed file size is : " + compressed.length() + " bytes");
return compressed;
}
I'm using the code below to read a Unix socket:
Boolean flag = false;
while (!flag) {
try {
File socketFile = new File("./RISP");
AFUNIXSocket sock = AFUNIXSocket.newInstance();
sock.connect(new AFUNIXSocketAddress(socketFile));
System.out.println("!!!!!!!!!!CONNECTED!!!!!!!!!");
flag = true;
BufferedReader input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String line = null;
while ((line = input.readLine())!=null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("NOT CONNECTED....." + e);
}
try {
Thread.sleep(2000);
} catch (InterruptedException inter) {
System.out.println(inter);
}
}
I need to read the first 4 bytes of each pack and convert them from binary to integer.
I've read many posts but I'm still looking for the best solution to my problem.
Reader and Writer are designed for reading text.
For binary, you should try InputStream and OutputStream, in this case, you want DataInputStream, possibly buffered.
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
int len = in.readInt(); // read big-endian.
if (LITTLE_ENDIAN)
len = Integer.reverseBytes(len);
byte[] bytes = new byte[len];
in.readFully(bytes);
seems it works
DataInputStream in = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
int len = -1;
while ((len = in.readInt()) != -1) {
len = Integer.reverseBytes(len);
byte[] bytes = new byte[len];
in.readFully(bytes);
if (bytes.length > 4) {
System.out.println(" BYTE0: " + bytes[0] +
" BYTE1: " + bytes[1] +
" BYTE2: " + bytes[2] +
" BYTE2: " + bytes[3] +
" LENGHT: " + bytes.length);
}
}
please let me know is i miss something.
thanks a lot to you guys.
I'm using sockets for file transfer in java.
Here is the Client code
for(int i = 0;i < fileList.size();i++) {
String filename = (String)fileList.get(i);
RequestFile(filename);
try {
BufferedOutputStream fileWriter = new BufferedOutputStream(
new FileOutputStream(
new File(PROGRAM_PATH + "/" +
filename)));
int packet;
int count = 0;
while((packet = fileReader.read()) != -1) {
fileWriter.write(packet);
count++;
}
System.out.println(filename + " receiver complete. (count : " + count + ")");
fileWriter.flush();
fileWriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
And here is the Server code
public void SendFile(String filename) {
try {
fileReader = new BufferedInputStream(new FileInputStream(CLIENT_PATH + "/" + filename));
int packet;
int count = 0;
while((packet = fileReader.read()) != -1) {
count++;
fileWriter.write(packet);
}
fileWriter.write(-1);
System.out.println(count);
fileReader.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
When I checked the server's count, it was 635. It means the server had sent data 635 times.
However, the client's print count is only 512. (from 0 to 511) I think it's stopped at read(), because
System.out.println(filename + " receiver complete. (count : " + count + ")");
is not printed. Can someone tell me the reason and solution?
At the server side you can't send a byte with value -1 to the client. This line:
fileWriter.write(-1);
It does not do what you want. The write() method will take the lowest 8 bits of the parameter and send that as one byte (which in this case will be 0xff). At the client side fileReader.read() will receive this as 0xff (of type int) and not as -1 (of type int).
-1 is a special value indicating that end of stream has been reached. It is not a valid data to be written or read. If you send -1, the client will read that as 0xff=255. The values that can be sent and received is 0..255 both inclusive. Again, -1 is a special value for end-of-stream.
At the server side you don't flush or close the output stream. That might explain the difference (data hold in the buffer might not get through to the client).
I'm trying to create a file that maps every possible binary combination of some part of speech tags, and for some reason the java program I've written just stops after 8192 bytes. I assume that this is the maximum buffer size or something? How can I change that?
My code:
try {
Scanner in = new Scanner(new FileInputStream(file.getPath()));
PrintWriter out = new PrintWriter(new FileOutputStream("S2.gr"));
createS2(in, out);
} catch (Exception e) {
System.out.println("There was an error trying to open the files: " + e.getMessage());
}
private static void createS2(Scanner in, PrintWriter out) {
String[] pos = in.useDelimiter("\\A").next().split("\\n");
out.println("1\tS2");
for (String x : pos) {
out.println("1\tS2\t_" + x);
}
for (String x : pos) {
String temp = ("1\t_" + x + "\t" + x);
out.println(temp);
for (String y : pos) {
out.println(temp + " _" + y);
}
}
for (String x : pos) {
System.out.println(x);
}
}
Try this...
Scanner in = null;
PrintWriter out = null;
try {
in = new Scanner(new FileInputStream(file.getPath()));
out = new PrintWriter(new FileOutputStream("S2.gr"));
createS2(in, out);
} catch (Exception e) {
System.out.println("There was an error trying to open the files: " + e.getMessage());
}
finally {
if(in != null) in.close();
if(out != null) out.close();
}
Note: if you're using Java 7, there's a new feature to make this easier. e.g.
try (Scanner in = new Scanner(new FileInputStream(file.getPath()));
PrintWriter out = new PrintWriter(new FileOutputStream("S2.gr")))
{
createS2(in, out);
} catch (Exception e) {
System.out.println("There was an error trying to open the files: " + e.getMessage());
}
Note: I don't have a JDK 7 available to me at the moment, so the second example might not be 100% correct, but the idea is that the new language feature can manage closing resources for you.
I want to know if really 'put' has succeeded in putting the file to destination. If for any reason the file is not put in destination [maybe due to problems in destination server like space constraint, etc] I need to know that.
Code:
private static boolean putFile(String m_sLocalFile, FtpClient m_client) {
boolean success = false;
int BUFFER_SIZE = 10240;
if (m_sLocalFile.length() == 0) {
System.out.println("Please enter file name");
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
File f = new File(m_sLocalFile);
int size = (int) f.length();
System.out.println("File " + m_sLocalFile + ": " + size + " bytes");
System.out.println(size);
FileInputStream in = new FileInputStream(m_sLocalFile);
OutputStream out = m_client.put(f.getName());
int counter = 0;
while (true) {
int bytes = in.read(buffer);
if (bytes < 0)
break;
out.write(buffer, 0, bytes);
counter += bytes;
System.out.println(counter);
}
out.close();
in.close();
} catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
return success;
}
I would expect it to throw an IOException. Do you have any reason to believe it doesn't? But you shouldn't be using that class directly, you should be using an ftp: URL and its URLConnection class to do the I/O with, after calling setDoOutput(true).