Hi everyone i am practicing with java data input output stream. But i don't know how to fix this problem i can write data input stream to my file but can't read it
here is my code:
public static void readDataIOStream(){
DataInputStream dataIn = null;
int i = 10;
double d = 1023.56;
boolean b = true;
try {
dataIn = new DataInputStream(
new FileInputStream("test.txt"));
i = dataIn.readInt();
System.out.println("Reading " + i);
d = dataIn.readDouble();
System.out.println("Reading " + d);
b = dataIn.readBoolean();
System.out.println("Reading " + b);
d = dataIn.readDouble();
System.out.println("Reading " + d);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}try {
dataIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void writeDataIOStream(){
DataOutputStream dataOut = null;
int i = 10;
double d = 1023.56;
boolean b = true;
try {
dataOut = new DataOutputStream(new FileOutputStream("test.txt"));
System.out.println("Writing " + i);
dataOut.write(i);
System.out.println("Writing " + d);
dataOut.writeDouble(d);
System.out.println("Writing " + b);
dataOut.writeBoolean(b);
System.out.println("Writing " + 12.2 * 7.4);
dataOut.writeDouble(12.2 * 7.4);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
dataOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and here is error :
java.io.EOFException
at java.io.DataInputStream.readFully(Unknown Source)
at java.io.DataInputStream.readLong(Unknown Source)
at java.io.DataInputStream.readDouble(Unknown Source)
at bytestream.DataIOStream.readDataIOStream(DataIOStream.java:108)
at bytestream.DataIOStream.main(DataIOStream.java:16)
Writing 10
Writing 1023.56
Writing true
Writing 90.28
Reading 172003324
Reading 8.029891292620447E283
Reading true
Please help me why i can't read Data Input stream
dataOut.write(i) only writes one byte. Yet you are reading an int doing i = dataIn.readInt() which is 4 bytes.
Therefore when trying to read the last element which is a double, there is only 5 bytes in the stream while it is trying to read 8 bytes (the length of a double), hence the exception.
Since you want to write/read an int, you need to call dataOut.writeInt(i) instead of dataOut.write(i).
Related
I'm working on a multi-threaded web-server for a school project. I should be able to go into the localhost on my browser and request 3 different files (.htm, .jpeg,.pdf). However, when I do this for a .htm file with the picture also inside of it (2 requests) the .htm file appears in browser but I get many broken pipe socket exceptions for each write I try to do on the picture (Assignment requires to write 1024 bytes at a time). Something is clearly wrong with the way I have implemented this but I am at a loss as to where the connection is being closed when I try to write for the second file?
I tried a few different things to try and fix this including a loop when trying to read the socket input stream but I think that defeats the purpose of the multi-threaded server.
The server:
while(true){
try {
sock = servSock.accept(); // Handles the connection
// Connection received log
System.out.println("Connection received: " + new Date().toString() + " at " + sock.getInetAddress() + sock.getPort());
HTTP pro = new HTTP(sock); // Client handler
pro.run();
ServerThread serverThread = new ServerThread(pro);
// Starts ServerThread
serverThread.start();
} catch (Exception e){
System.out.println(e);
}
}
HTTP:
public void run(){
// Try to open reader
try{
readSock = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (Exception e){
System.out.println(e);
}
// Open output stream
try{
this.out = new DataOutputStream(sock.getOutputStream());
this.printOut = new PrintWriter(sock.getOutputStream());
} catch (Exception e){
System.out.println(e);
}
// Try to read incoming line
try {
this.reqMes = readSock.readLine();
} catch (IOException e) {
e.printStackTrace();
}
StringTokenizer st = new StringTokenizer(reqMes);
// Parse the request message
int count = 0;
while(st.hasMoreTokens()){
String str = st.nextToken();
if (count == 1){
this.fileName = "." + str;
}
count += 1;
}
System.out.println("File name received.");
File file = null;
try {
file = new File(this.fileName);
this.f = new FileInputStream(file); // File input stream
this.fileExists = true;
System.out.println("File " + this.fileName + " exists.");
} catch (FileNotFoundException e) {
System.out.println(e);
this.fileExists = false;
System.out.println("File does not exist.");
}
byte[] buffer = new byte[1024];
// Write status line
if (this.fileExists) {
System.out.println("Trying to write data");
try{
this.out.writeBytes("HTTP/1.0 " + "200 OK " + this.CRLF);
this.out.flush();
this.printOut.println("HTTP/1.0 " + "200 OK " + this.CRLF);
// Write Header
this.out.writeBytes("Content-type: " + getMime(this.fileName) + this.CRLF);
this.printOut.println("Content-type: " + getMime(this.fileName) + this.CRLF);
this.out.flush();
// Read file data
byte[] fileData = new byte[1024];
while (this.f.read(fileData) != -1) {
// Write File data
try{
this.out.write(fileData,0,1024);
this.out.flush(); // Flush output stream
} catch (IOException e) {
System.out.println(e);
}
}
System.out.println("Flushed");
} catch (IOException e) {
e.printStackTrace();
}
}
For one .htm file in the browser, the file and html seem to appear fine. But it looks like it makes a second request for a .jpeg file within the html file and the browser gets stuck loading with java.net.SocketException: Broken pipe (Write failed) when writing the data each time at
this.out.write(fileData,0,1024);
Thank you, any help is appreciated.
After much searching among different problems, I found the answer here.
The problem was with the response headers not being formatted properly which led to the connection ending prematurely. Another empty line ("\r\n") must be sent after the header.
The following code now works (this.CRLF is equal to "\r\n"):
public void run(){
// Try to open reader
try{
readSock = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (Exception e){
System.out.println(e);
}
// Open output stream
try{
this.out = new DataOutputStream(sock.getOutputStream()); // Data output
this.printOut = new PrintWriter(sock.getOutputStream()); // Print output
} catch (Exception e){
System.out.println(e);
}
// Try to read incoming line
try {
this.reqMes = readSock.readLine();
} catch (IOException e) {
e.printStackTrace();
}
StringTokenizer st = new StringTokenizer(reqMes);
// Parse the request message
int count = 0;
while(st.hasMoreTokens()){
String str = st.nextToken();
if (count == 1){
this.fileName = "." + str;
}
count += 1;
}
System.out.println("File name received.");
// Initialize file to be sent
File file = null;
// Try to find file and create input stream
try {
file = new File(this.fileName);
this.f = new FileInputStream(file); // File input stream
this.fileExists = true;
System.out.println("File " + this.fileName + " exists.");
} catch (FileNotFoundException e) {
System.out.println(e);
this.fileExists = false;
System.out.println("File does not exist.");
}
byte[] buffer = new byte[1024];
// Write status line
if (this.fileExists) {
System.out.println("Trying to write data");
try{
this.out.writeBytes("HTTP/1.0 " + "200 OK " + this.CRLF);
this.out.flush();
// Write Header
this.out.writeBytes("Content-type: " + getMime(this.fileName) + this.CRLF);
this.out.flush();
this.out.writeBytes(this.CRLF);
this.out.flush();
// Read file data
byte[] fileData = new byte[1024];
int i;
while ((i = this.f.read(fileData)) > 0) {
// Write File data
try{
this.out.write(fileData,0, i);
} catch (IOException e) {
System.out.println(e);
}
}
this.out.flush(); // Flush output stream
System.out.println("Flushed");
closeSock(); // Closes socket
} catch (IOException e) {
e.printStackTrace();
}
I currently have a file download process in my java class, listed below, to take all the data in an SQL table and put it in a CSV file for user download. However, when I download the file, all the data is good except it will cut off at random points (usually around line 20 of the data, given there are at least over 100 lines of data). I want to ask, what if making the cutoff? Is it session time related or is the code just problematic?
public String processFileDownload() {
DataBaseBean ckear = new DataBaseBean();
ckear.clearContens();
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
Map<String, Object> m = fc.getExternalContext().getSessionMap();
dbase = (DbaseBean) m.get("dbaseBean");
message = (MessageBean) m.get("messageBean");
dataBean = (DataBean) m.get("dataBean");
dbmsUser = (DbmsUserBean) m.get("dbmsUserBean");
FileOutputStream fos = null;
String path = fc.getExternalContext().getRealPath("/temp");
String tableName = dbmsUser.getTableName();
String fileNameBase = tableName + ".csv";
java.net.URL check = getClass().getClassLoader().getResource(
"config.properties");
File check2 = new File(check.getPath());
path = check2.getParent();
String fileName = path + "/" + dbmsUser.getUserName() + "_"
+ fileNameBase;
File f = new File(fileName);
try {
f.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
dbase.connect();
dbase.setQueryType("SELECT");
dbase.executeSQL("select * from " + tableName);
if (dbase.getResultSet() == null) {
FacesContext.getCurrentInstance().addMessage("myForm3:errmess",
new FacesMessage("Table doesn't exist!"));
return "failed";
}
Result result = ResultSupport.toResult(dbase.getResultSet());
downlaodedrows = result.getRowCount();
Object[][] sData = result.getRowsByIndex();
String columnNames[] = result.getColumnNames();
StringBuffer sb = new StringBuffer();
try {
fos = new FileOutputStream(fileName);
for (int i = 0; i < columnNames.length; i++) {
sb.append(columnNames[i].toString() + ",");
}
sb.append("\n");
fos.write(sb.toString().getBytes());
for (int i = 0; i < sData.length; i++) {
sb = new StringBuffer();
for (int j = 0; j < sData[0].length; j++) {
sb.append(sData[i][j].toString() + ",");
}
sb.append("\n");
fos.write(sb.toString().getBytes());
}
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String mimeType = ec.getMimeType(fileName);
FileInputStream in = null;
byte b;
ec.responseReset();
ec.setResponseContentType(mimeType);
ec.setResponseContentLength((int) f.length());
ec.setResponseHeader("Content-Disposition", "attachment; filename=\""
+ fileNameBase + "\"");
try {
in = new FileInputStream(f);
OutputStream output = ec.getResponseOutputStream();
while (true) {
b = (byte) in.read();
if (b < 0)
break;
output.write(b);
}
} catch (NullPointerException e) {
fc.responseComplete();
return "SUCCESS";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
fc.responseComplete();
return "SUCCESS";
}
The problem seems to be that you are simply appending commas between values and it's likely one of the values you are writing contains a delimiter, line separator or quote character, which will "break" the CSV format if not correctly escaped.
It would be way easier and faster to use CSV library for that. uniVocity-parsers comes with pre-built routines to dump your resultset into properly formatted CSV. In your case, you could use this library in the following manner:
ResultSet resultSet = dbase.getResultSet();
// Configure the output format as needed before actually dumping the data:
CsvWriterSettings writerSettings = new CsvWriterSettings(); //many settings here, check the tutorials & examples.
writerSettings.getFormat().setLineSeparator("\n");
writerSettings.setHeaderWritingEnabled(true); // we want the column names to be printed out as well.
// Then create a routines object:
CsvRoutines routines = new CsvRoutines(writerSettings);
// The write() method takes care of everything. The resultSet and any other resources required are closed by the routine.
routines.write(resultSet, new File(fileName), "UTF-8");
Hope this helps
Disclaimer: I'm the author of this library. It's open source and free (Apache 2.0. license)
I'm trying to create a simple recorder which gives 'pause' and 'resume' functionality to the user.
Since Android does not support this directly, I'm creating individual files whenever the user presses 'Pause' and 'Resume' with the suffixes _1, _2, so on.
I use the code below to concatenate them
public void mergeAllAndSave() {
// TODO Auto-generated method stub
Enumeration<FileInputStream> allRecordings;
Vector<FileInputStream> audiofiles = new Vector<FileInputStream>();
for (int i = 1; i < count+1; i++) {
try {
audiofiles.add(new FileInputStream(Environment.getExternalStorageDirectory().getPath() + "/"+ AUDIO_RECORDER_FOLDER + "/" + _filename + "_"+ i + file_exts[currentFormat]));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
allRecordings = audiofiles.elements();
SequenceInputStream siStream = new SequenceInputStream(allRecordings);
try {
FileOutputStream foStream = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/"+ AUDIO_RECORDER_FOLDER + "/" + _filename + file_exts[currentFormat]);
int temp;
while ((temp = siStream.read() ) != -1) {
foStream.write(temp);
}
foStream.close();
siStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The code works fine. It gives me a single file. However it contains the contents of the first file only. Logcat does not show any errors, whatsoever.
Anyone with any ideas what is the mistake I am making?
Thanks.
Answer to this question is here.
PS: I cannot add this as a comment because I do not have sufficient reputation.
mates!
I have trouble reading from file Cyrillic text using RandomAccessFile.
Here's a simple program, that writes information in specific file (Cyrillic words) using such format:
keyLength, valueLength, key, value
Then program tries to read this information, but my output is incorrect:
writing success
keyLength = 10, valueLength = 4
read: килло, гр
UPD
Expected output:
writing success
keyLength = 10, valueLength = 4
read: киллограмм, сала
What is the problem? (except problem that I have small brain)
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String fileName = "file.db";
RandomAccessFile outputFile = null;
try {
outputFile = new RandomAccessFile(fileName, "rw");
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
System.exit(1);
}
String key = "киллограмм";
String value = "сала";
try {
outputFile.writeInt(key.length());
outputFile.writeInt(value.length());
outputFile.write(key.getBytes("UTF-8"));
outputFile.write(value.getBytes("UTF-8"));
} catch (IOException e) {
System.err.println(e.getMessage());
System.exit(1);
}
System.out.println("writing success");
RandomAccessFile inputFile = null;
try {
inputFile = new RandomAccessFile(fileName, "r");
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
System.exit(1);
}
int keyLength = 0, valueLength = 0;
try {
keyLength = inputFile.readInt();
valueLength = inputFile.readInt();
} catch (IOException e) {
System.err.println(e.getMessage());
}
System.out.println("keyLength = " + keyLength + ", valueLength = " + valueLength);
if (keyLength <= 0 || valueLength <= 0) {
System.err.println("key or value length is negative");
System.exit(1);
}
byte[] keyBytes = null, valueBytes = null;
try {
keyBytes = new byte[keyLength];
valueBytes = new byte[valueLength];
} catch (OutOfMemoryError e) {
System.err.println(e.getMessage());
System.exit(1);
}
try {
inputFile.read(keyBytes);
inputFile.read(valueBytes);
} catch (IOException e) {
System.err.println(e.getMessage());
System.exit(1);
}
try {
System.out.println("read: " + new String(keyBytes, "UTF-8") + ", " + new String(valueBytes, "UTF-8"));
} catch (IOException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}
The issue is this
outputFile.writeInt(key.length());
String#length()
Returns the length of this string. The length is equal to the number
of Unicode code units in the string.
In this case, it returns the value 10, which is not the number of byte required to represent this String.
What you want is
key.getBytes("UTF-8").length
used as
byte[] keyBytes = key.getBytes("UTF-8");
outputFile.writeInt(keyBytes.length);
Same for the value.
I have followed some tutorials to create a basic server that can handle multiple clients at once. It receives data correctly but it chews up more and more memory until it runs out of heap space. I believe it is because my loop is not recognising my end character and leaving the for loop.
Here is the code for the thread which receives the data:
while (true){
try {
is = new BufferedInputStream(s.getInputStream());
InputStreamReader isr = new InputStreamReader(is);
int character;
StringBuilder process = new StringBuilder();
try {
while((character = isr.read()) != 13) {
process.append((char)character); //here is the issue - it just continues to append until it runs out of memory
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
parent.parent.writeToLog("Client " + Integer.toString(num) + " sent a message: " + process.toString());
System.out.println(process);
is = null;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedOutputStream os;
try {
os = new BufferedOutputStream(s.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os);
osw.write("Response from server at client socket " + Integer.toString(num) + " at " + (new java.util.Date()).toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I've put a comment into the code where it shows me the error on the stack trace. Here is the client, which is just the EchoClient from the Java tutorials:
import java.io.*;
import java.net.*;
import java.util.Random;
public class EchoClient {
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket("localhost", 2405);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
out.println("Message to host: hello" + (char) 13);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.println(Integer.toString((new Random()).nextInt()) + (char) 13);
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
You can see where I append the character 13 to the output and that is what is meant to end the loop but from my understanding this is not working. Could anyone help me out with this?
I think the problem lies in the following code:
while((character = isr.read()) != 13) {
process.append((char)character); //here is the issue - it just continues to append until it runs out of memory
}
Even when end of stream is reached isr.read() would return -1 and not 13. There's a possibility that you are never receiving input character that is 13 to exit out of the loop.
This is likely the problem: while((character = isr.read()) != 13)
Why are you checking for 13? InputStreamReader.read() will return -1 if the end of the stream is reached.
My guess is that you're hitting the end of the stream and filling your StringBuilder with garbage. Note that (char)-1 actually represents the unicode character 65535.