im trying to send a file in android through sockets. i want to add the filename with the bytestream and then send it to the server. how do i do that? and then how do i seperate the filename on the receiving side?
this is the code to send file :
Log.i("SocketOP", "sendFILE-1");
File f = new File(path);
String filename=path.substring(path.lastIndexOf("/")+1);
System.out.println("filename:"+filename);
fin.filename = "~"+filename;
BufferedOutputStream out = new BufferedOutputStream( socket.getOutputStream() );
FileInputStream fileIn = new FileInputStream(f);
Log.i("SocketOP", "sendFILE-2");
byte [] buffer = new byte [(int)f.length()];
System.out.println("SO sendFile f.length();" + f.length());
int bytesRead =0;
while ((bytesRead = fileIn.read(buffer)) > 0) {
out.write(buffer, 0, buffer.length);
System.out.println("SO sendFile" + bytesRead +filename);
}
out.flush();
out.close();
fileIn.close();
Log.i("SocketOP", "sendFILE-3");
If this is your own protocol then you create a data packet that separate the two sections (filename and data). You need to denote clearly the separation via a particular boundary.
On the server, since you understand the protocol, the server will read back the whole data packet and it will separate the filename and data based on the given boundary.
MIME data format use exactly this kind of data exchange and widely use with HTTP protocol. If you use the same MIME Data Format, another advantage is you could use third party library to encode and decode your data such as HttpMime
Below is the rough code to format the data using MIME data and send it through Socket
File f = new File(path);
BufferedOutputStream out = new BufferedOutputStream( socket.getOutputStream() );
String filename=path.substring(path.lastIndexOf("/")+1);
// create a multipart message
MultipartEntity multipartContent = new MultipartEntity();
// send the file inputstream as data
InputStreamBody isb = new InputStreamBody(new FileInputStream(f), "image/jpeg", filename);
// add key value pair. The key "imageFile" is arbitrary
multipartContent.addPart("imageFile", isb);
multipartContent.writeTo(out);
out.flush();
out.close();
Note that you would need org.apache.http.entity.mime.MultipartEntity and org.apache.http.entity.mime.content.InputStreamBody from HttpMime project. On the server, you need MIME parser that would get back the filename and all the bytes content
To read the inputstream back on the server, you would need a class to parse the MIME message. You shouldn't have to write the parser yourself as MIME is a popular message format already unless you want to learn about the MIME message structure.
Below is the sample code using MimeBodyPart that is part of JavaMail.
MimeMultipart multiPartMessage = new MimeMultipart(new DataSource() {
#Override
public String getContentType() {
// this could be anything need be, this is just my test case and illustration
return "image/jpeg";
}
#Override
public InputStream getInputStream() throws IOException {
// socket is the socket that you get from Socket.accept()
BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream());
return inputStream;
}
#Override
public String getName() {
return "socketDataSource";
}
#Override
public OutputStream getOutputStream() throws IOException {
return socket.getOutputStream();
}
});
// get the first body of the multipart message
BodyPart bodyPart = multiPartMessage.getBodyPart(0);
// get the filename back from the message
String filename = bodyPart.getFileName();
// get the inputstream back
InputStream bodyInputStream = bodyPart.getInputStream();
// do what you need to do here....
You could download JavaMail from Oracle Website which also has dependency on Java Activation Framework
Related
Hi I am uploading Large video files to server using Volley Multi-part Api but it takes much time for upload to server
Is it better to split my video files and send to server? If it is better please provide me code how can I do that, If not what is the best way to uploading big videos files to server quickly?
To split file into parts (chunks):
public static List<File> splitFile(File f) throws IOException {
int partCounter = 1;
List<File> result = new ArrayList<>();
int sizeOfFiles = 1024 * 1024;// 1MB
byte[] buffer = new byte[sizeOfFiles]; // create a buffer of bytes sized as the one chunk size
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
String name = f.getName();
int tmp = 0;
while ((tmp = bis.read(buffer)) > 0) {
File newFile = new File(f.getParent(), name + "." + String.format("%03d", partCounter++)); // naming files as <inputFileName>.001, <inputFileName>.002, ...
FileOutputStream out = new FileOutputStream(newFile);
out.write(buffer, 0, tmp);//tmp is chunk size. Need it for the last chunk, which could be less then 1 mb.
result.add(newFile);
}
return result;
}
This method will split your file to chunks of size of 1MB (excluding the last chunk). After words you can send all these chunks too the server.
Also if you need to merge these files:
public static void mergeFiles(List<File> files, File into)
throws IOException {
BufferedOutputStream mergingStream = new BufferedOutputStream(new FileOutputStream(into))
for (File f : files) {
InputStream is = new FileInputStream(f);
Files.copy(is, mergingStream);
is.close();
}
mergingStream.close();
}
Just in case if your server is in Java also
im writing a socket program which send and receive strings.
Im trying to build a file using this received strings that are sending from other side.
this is exactly done with text files but in others such an image file doesn't work and when complete, the image does not open!
in receiver:
file = new File(dir,FileName);
fOut = new FileOutputStream(file);
dos = new DataOutputStream(fOut);
and when a msg received:
dos.write(msg.getBytes("UTF-8"));
in sender:
File file = new File(FilePath);
InputStream is = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(is);
...
isr.read(inputBuffer);
I have Tried this solution but the problem didn't fixed:
Changing the UTF-8 to ISO-8859-1
using output stream writer instead of data output stream.
trying with smaller pictures than text file.
ByteArrayOutputStream is useful converting bitmap to byte array.
after then, you using BitmapFactory, decodeByteArray is converting byte to bitmap.
I am trying to send some binary data that is stored on the Android phone as a file to the web service that is created in PHP.
I have tried using MultiPart as well as ValuePair but no luck..!!
What I also did is to create a console application in Java, which reads the binary file from a static location on Windows and use the same PHP service and it works fine using MultiPart, below is the code for that:
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file,"text/plain");
mpEntity.addPart("qLog", new StringBody(readFileAsString(file.getAbsolutePath()),
Charset.defaultcharset)));
mpEntity.addPart("fileName", new StringBody(fileName));
mpEntity.addPart("personid", new StringBody(userid));
and the function readFileAsString() is:
private String readFileAsString(String filePath) throws IOException {
StringBuffer fileData = new StringBuffer();
BufferedReader reader = new BufferedReader(new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while ((numRead=reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
return fileData.toString();
}
But when I do this on Android it is not maintaining the binary values. The reason I think is due to the default encoding in Android is UTF-8.
Can you please help here? How do I get the binary data sent from Android to PHP Service?
You can use InputStreamBody instead of StringBody:
MultipartEntity mpEntity = new MultipartEntity();
mpEntity.addPart("qLog", new InputStreamBody(new FileInputStream(file),
file.getName());
mpEntity.addPart("fileName", new StringBody(fileName));
mpEntity.addPart("personid", new StringBody(userid));
Edited
Or you can use FileBody for more concise.
I have a multipart format text file. i am going threw the file looking for start of content and from then on writing the content to another file until i hit end of content.
FileInputStream in = new FileInputStream(getContentPath());
InputStreamReader sr = new InputStreamReader(in, "UTF-8");
BufferedReader buffreader = new BufferedReader(sr);
String lineStr;
while ((lineStr = buffreader.readLine()) != null) {
if (lineStr == "") {
FileOutputStream fos = new FileOutputStream("", true);
OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter fbw = new BufferedWriter(writer);
fbw.write(lineStr);
fbw.newLine();
fbw.flush();
fbw.close();
}
}
The problem i am getting is the resulting files encoding is all messed up. The input is utf8.
Original in multipart format
Just image file extracted(funny-pictures-bomb-squad-cat-chooses-the-blue-wire.jpg)
Found problem the input charset was not utf8 it is iso-8859-1 http default.
Used CharsetDecoder to make sure i read/saved string as iso-8859-1.
FileWriter writer = new FileWriter(highscoresFile, true);
The boolean at the end tells you whether or not to append to the end of the file.
I know basic socket programming.
I have a code to send strings using sockets in android.
I want to learn how to send a file (MP3,image etc) using sockets between two phones.
This is some code to send a file. It should work just like you would expect outside of Android. I knew I was sending files that were relatively small, so you might want to make more than one pass through a buffer. The File "f" in my example should just be replaced with the File that contains your MP3 or Image or whatever you want to send.
public void sendFile() throws IOException{
socket = new Socket(InetAddress.getByName(host), port);
outputStream = socket.getOutputStream();
File f = new File(path);
byte [] buffer = new byte[(int)f.length()];
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(buffer,0,buffer.length);
outputStream.write(buffer,0,buffer.length);
outputStream.flush();
}