I am trying to share files between two Android phones using Socket programming. The problem is right now I have to hard code the file extension on the receiving end. Is there a way that I can automatically determine the extension of the file being received?
Here's my code.
Client Side
socket = new Socket(IP,4445);
File myFile = new File ("/mnt/sdcard/Pictures/A.jpg");
FileInputStream fis = null;
fis = new FileInputStream(myFile);
OutputStream os = null;
os = socket.getOutputStream();
int filesize = (int) myFile.length();
byte [] buffer = new byte [filesize];
int bytesRead =0;
while ((bytesRead = fis.read(buffer)) > 0) {
os.write(buffer, 0, bytesRead);
System.out.println("SO sendFile" + bytesRead);
}
os.flush();
os.close();
fis.close();
socket.close();
}
And the Server side
FileOutputStream fos = null;
File root = Environment.getExternalStorageDirectory();
fos = new FileOutputStream(new File(root,"B.jpg")); //Here I have to hardcode B.jpg with jpg extension.
BufferedOutputStream bos = new BufferedOutputStream(fos);
ServerS = new ServerSocket(4445);
clientSocket = ServerS.accept();
InputStream is = null;
is = clientSocket.getInputStream();
int bytesRead = 0;
int current = 0;
byte [] mybytearray = new byte [329];
do {
bos.write(mybytearray,0,bytesRead);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
} while(bytesRead > -1);
bos.flush();
bos.close();
clientSocket.close();
}
You can find the file extension pretty easily by doing this:
String extension = filename.substring(filename.lastIndexOf('.'));
Related
I have a method that takes an image's URL and attempts to save it in memory. I need to retrieve this saved file later, and want to do so by getting its file path. How do I get the file name from this save method?
InputStream input;
try {
URL url = new URL (strURL);
input = url.openStream();
byte[] buffer = new byte[1500];
OutputStream output = new FileOutputStream ("/sdcard/"+pos+".png");
try {
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
}
finally {
output.close();
buffer = null;
}
}
I am using Android Studio.
I'm getting data from an api and I want to write/save some file with that data. This is my code
try
{
HttpResponse response = httpClient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/incubate_files");
if (!myDir.exists()) myDir.mkdirs();
File file = new File(Environment.getExternalStorageDirectory().getPath()+File.separator+"/incubate_files/", "messageId_"+messageId+"."+ext);
FileOutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bufferLength = 0;
while((bufferLength = content.read(buffer)) != -1)
output.write(buffer, 0, bufferLength);
output.close();
output.flush();
content.close();
}
catch (Exception e)
{
e.printStackTrace();
}
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
There is no exception, only a empty file
Thanks!
UPDATE
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null)
{
builder.append(line);
}
Log.d(app.TAG,"Cadena: "+builder.toString());
InputStream is = new ByteArrayInputStream(builder.toString().getBytes());
I change my InputStream white the content of the api. The api returns a lot of characters. The image actually exists in the server and I can see it.
Now the file is with some bytes but I cant see in my phone
The api reponse is in binary
You need to make use of getInputStream method from connection object and save the data into a File. For example:
InputStream input = connection.getInputStream();
File file = new File("download_directory_path", "file_name");
FileOutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bufferLength = 0;
while((bufferLength = input.read(buffer)) != -1)
output.write(buffer, 0, bufferLength);
and then finally close() your output and input streams.
Once, writing is complete, the file points to the downloaded file.
hi i transferred an image from server socket to client socket between two android devices. i got the image but it is 0 bytes in size.here is my code
sender:
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
File myFile = new File("/sdcard/DCIM/d.png");
byte [] mybytearray = new byte[(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = client.getOutputStream();
serverStatus.setText("sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
client.close();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
receiver:
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
connected = true;
byte[] mybytearray = new byte[filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("/sdcard/j.png");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do{
bytesRead = is.read(mybytearray,current,(mybytearray.length-current));
if(bytesRead > 0){
current +=bytesRead;
}
}while(bytesRead > 0);
bos.write(mybytearray,0,current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
socket.close();
while (connected) {
try {
Log.d("ClientActivity", "C: Sending command.");
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
// WHERE YOU ISSUE THE COMMANDS
out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
is anything wrong in this code? thanks in advance..
is anything wrong in this code?
You bet.
byte [] mybytearray = new byte[(int)myFile.length()];
Here you are assuming (1) that the file's length fits into an int, and (2) that the file contents will fit into memory.
bis.read(mybytearray,0,mybytearray.length);
Here you are assuming the read fills the buffer.
byte[] mybytearray = new byte[filesize];
Here you are again assuming (3) that the file contents will fit into memory, and (4) that filesize is indeed the correct length of the file. You haven't shown how the receiver can possibly know that.
bytesRead = is.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
do {
bytesRead = is.read(mybytearray, current, (mybytearray.length - current));
if (bytesRead > 0) {
current += bytesRead;
}
} while (bytesRead > 0);
bos.write(mybytearray, 0, current);
Here you (5) aren't checking the result of the first read and (6) pointlessly reading the entire input into a buffer. You don't need to do that. The canonical way to copy a stream in Java is as follows:
while ((count = in.read(buffer)) < 0){
out.write(buffer, 0, count);
}
It works at both ends, i.e. for sending and receiving, and with any buffer size greater than zero. Use this both for sending the file and receiving it.
i am writing the PDF's to sdcard and using the below code :
byte[] data = new byte[20000];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
InputStream fileInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
while ((nRead = fileInputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] bytesToWrite = buffer.toByteArray();
fileInputStream.read(bytesToWrite);
fileInputStream.close();
FileOutputStream fileOutputStream = null;
String outputFileName = outputDirName + "/" + fileName;
fileOutputStream = new FileOutputStream(outputFileName);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
bos.write(bytesToWrite);
bos.flush();
bos.close();
It works fine if i am trying to write 20 PDFs in one shot, but if its more than that it gives me OutOfMemory error.
what might be the issue ?
You are storing the entire file into RAM with your ByteArrayOutputStream, then copying it from RAM onto disk. This is likely what's causing your OutOfMemoryError.
It would be much more efficient to read a chunk into RAM, and then flush to disk immediately repeatedly. I've rewritten your code to do this.
byte[] data = new byte[20000];
FileOutputStream fileOutputStream = null;
String outputFileName = outputDirName + "/" + fileName;
fileOutputStream = new FileOutputStream(outputFileName);
int nRead;
InputStream fileInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
while ((nRead = fileInputStream.read(data, 0, data.length)) != -1) {
fileOutputStream.write(data,0,nRead);
}
fileInputStream.close();
fileOutputStream.flush();
fileOutputStream.close();
I have an API call that returns a byte array. I currently stream the result into a byte array then make sure the checksums match and then write the ByteArrayOutputStream to File. The code is something like this and it works pretty well.
String path = "file.txt";
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
FileOutputStream stream = new FileOutputStream(path);
stream.write(byteBuffer.toByteArray());
My concern i that the result from inputstream could potentially be larger than the heap size in android and I could get OutOfMemory exceptions if the entire byte array is in memory. What is the most elegant way to write the inputStream to file in chunks, such that the byte array is never larger than the heap size?
Don't write to the ByteArrayOutputStream. Write directly to the FileOutputStream.
String path = "file.txt";
FileOutputStream output = new FileOutputStream(path);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
I went with the advice to skip the ByteArrayOutputStream and write to the FileOutputStream and this seems to address my concerns. With one quick adjustment, where the FileOutputStream is decorated by a BufferedOutputStream
String path = "file.txt";
OutputStream stream = new BufferedOutputStream(new FileOutputStream(path));
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = is.read(buffer)) != -1) {
stream.write(buffer, 0, len);
}
if(stream!=null)
stream.close();