I have build a server use PHP based on WAMP Server on my windows 10 computer. what I want to do is when I send a GET request, the show_files.php should return a JSON object to me. The JSON object contains file names in path F:\NetEaseMusic\download on my computer. Then I use a file name to send a POST request to download_file.php and it returns a data stream so that I can download file. When I use HttpURLConnection, everything works well. However, when I try send the POST request use socket, download_file.php can get the file_name param, but it can not find the target file in F:\NetEaseMusic\download. I show the code.
this is
this is download_file.php
<?php
if(empty($_POST["file_name"]))
{
echo "NO_FILE_NAME\n";
print_r($_POST);
exit();
}
$path = iconv("utf-8", "GB2312","F:\\NetEaseMusic\\download\\".$_POST["file_name"]);
//$path = "F:\\NetEaseMusic\\download\\".$_POST["file_name"];
if (!file_exists ( $path )) {
echo "FILE_NOT_FOUND\n";
echo "F:\\NetEaseMusic\\download\\".$_POST["file_name"]."\n";
print($path);
exit ();
}
$file_size = filesize($path);
//header("Content-type: application/octet-stream");
//header("Accept-Ranges: bytes");
//header("Accept-Length:".$file_size);
//header("Content-Disposition: attachment; filename=".$path);
$file = fopen($path, "r");
while(!feof($file))
{
echo fread($file, 1024);
}
exit();
?>
this is my Client code which to download file. First of all I build a HTTP POST request,
private void downloadFileBySocket(String urlString, String fileName)
{
try{
StringBuilder sb = new StringBuilder();
String data = URLEncoder.encode("file_name", "utf-8") + "=" + URLEncoder.encode(fileName, "utf-8") + "\r\n";
//String data = "&file_name="+fileName;
sb.append("POST " + urlString + " HTTP/1.1\r\n");
sb.append("Host: 10.206.68.242\r\n");
sb.append("Content-Type: application/x-www-form-urlencoded\r\n");
sb.append("Content-Length: " + data.length() + "\r\n");
sb.append("\r\n");
sb.append(data + "\r\n");
//sb.append( URLEncoder.encode("file_name", "utf-8") + "=" + URLEncoder.encode(fileName, "utf-8") + "\r\n");
System.out.println(sb.toString());
URL url = new URL(urlString);
Socket socket = new Socket(url.getHost(), url.getPort());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
writer.write(sb.toString());
writer.flush();
File file = new File("./" + fileName);
DataOutputStream out = null;
DataInputStream in = null;
try{
out = new DataOutputStream(new FileOutputStream(file));
in = new DataInputStream(socket.getInputStream());
byte[] buffer = new byte[1024];
int readBytes = 0;
while((readBytes = in.read(buffer)) != -1)
{
out.write(buffer, 0, readBytes);
}
out.flush();
}catch (Exception e1)
{
e1.printStackTrace();
}finally {
try{
if(in != null)
{
in.close();
}
if(out != null)
{
out.close();
}
}catch (Exception e2)
{
e2.printStackTrace();
}
}
socket.close();
}catch (Exception e)
{
e.printStackTrace();
}
}
and my main[] method
public static void main(String[] args)
{
SocketTest socketTest = new SocketTest();
socketTest.downloadFileBySocket(SocketTest.downloadFileUrl, "小胡仙儿 - 【二胡】霜雪千年.mp3");
}
Simple way:
using System.Net;
WebClient webClient = new WebClient();
webClient.DownloadFile("example.com/myfile.txt", #"c:/myfile.txt");
Related
I am trying to download a file from a php get url that has username and password. My code doesn't show any errors and the progress bar shows me that the file is downloaded but when I try to print the list inside the Log I cannot see the file. What am I doing wrong?
That's the code inside the doInBackground section in the AsyncTask which I have called inside the onCreate and have put the url inside the parameters.
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try{
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
input = connection.getInputStream();
output = new FileOutputStream(context.getFilesDir()+"video.m3u");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1){
total = total + count;
if (fileLength > 0){
publishProgress((int) (total * 100 / fileLength));
}
output.write(data, 0, count);
}
}catch (Exception e){
return e.toString();
}finally {
try{
if (output != null){
output.close();
}
if (input != null){
input.close();
}
}catch (IOException ignored){
}
if (connection != null){
connection.disconnect();
}
}
return "";
}
In the onPostExecute section I have written this code
if (result.equals("")){
String path = context.getFilesDir().toString();
Log.d("Files", "Path: "+ path);
File directory = new File(path);
File[] files = directory.listFiles();
Log.d("Files", "Size: " + files.length);
for (int i = 0; i<files.length; i++){
Log.d("Files", "File Name: " + files[i].getName());
}
}
But the only thing that I get printed is this:
D/Files: Path: /data/data/my.app.package/files
D/Files: Size: 1
D/Files: File Name: instant-run
I can't see the file that has been downloaded.
I think the problem is this line
output = new FileOutputStream(context.getFilesDir()+"video.m3u");
context.getFilesDir() doesn't return String, it's File object you need to do this
output = new FileOutputStream(context.getFilesDir()..getAbsolutePath()+"/video.m3u");
The file path you are saving to is wrong. Right now you are saving to
output = new FileOutputStream(context.getFilesDir()+"video.m3u");
it needs to be output = new FileOutputStream(context.getFilesDir().getAbsolutePath()+"/video.m3u");
Hopes this helps.
Can anyone help me to make my code work, i.e. upload a file from Android to the server via PHP? I tried it in many different ways but it won't work. I get HTTP Response 200 but the files aren't uploaded on server.
The PHP script I'm using for upload is:
<?php
$uploaddir = 'uploads/';
$uploadfile = $uploaddir . basename($_FILES['uploaded_file']['name']);
if (move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Possible file upload attack!\n";
}
echo 'Here is some more debugging info:';
print_r($_FILES);
?>
I also tried using multipart from Httpmime 4.0 but it wont work.
public void uploadFile(String path)
{
File file = new File(path);
try {
HttpClient client = new DefaultHttpClient();
String postURL = upLoadServerUri;
HttpPost post = new HttpPost(postURL);
FileBody bin = new FileBody(file);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("uploaded_file", bin);
post.setEntity(reqEntity);
HttpResponse response = client.execute(post);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
Log.i("RESPONSE Wahaj: ","Code : "+ EntityUtils.toString(resEntity));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class Helpher extends AsyncTask<String, Void, String> {
Context context;
JSONObject json;
ProgressDialog dialog;
int serverResponseCode = 0;
DataOutputStream dos = null;
FileInputStream fis = null;
BufferedReader br = null;
public Helpher(Context context) {
this.context = context;
}
protected void onPreExecute() {
dialog = ProgressDialog.show(Main2Activity.this, "ProgressDialog", "Wait!");
}
#Override
protected String doInBackground(String... arg0) {
try {
File f = new File(arg0[0]);
URL url = new URL("http://localhost:8888/imageupload.php");
int bytesRead;
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
String contentDisposition = "Content-Disposition: form-data; name=\"keyValueForFile\"; filename=\""
+ f.getName() + "\"";
String contentType = "Content-Type: application/octet-stream";
dos = new DataOutputStream(conn.getOutputStream());
fis = new FileInputStream(f);
dos.writeBytes(SPACER + BOUNDARY + NEW_LINE);
dos.writeBytes(contentDisposition + NEW_LINE);
dos.writeBytes(contentType + NEW_LINE);
dos.writeBytes(NEW_LINE);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
while ((bytesRead = fis.read(buffer)) != -1) {
dos.write(buffer, 0, bytesRead);
}
dos.writeBytes(NEW_LINE);
dos.writeBytes(SPACER + BOUNDARY + SPACER);
dos.flush();
int responseCode = conn.getResponseCode();
if (responseCode != 200) {
Log.w(TAG,
responseCode + " Error: " + conn.getResponseMessage());
return null;
}
br = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
Log.d(TAG, "Sucessfully uploaded " + f.getName());
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
try {
dos.close();
if (fis != null)
fis.close();
if (br != null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return String.valueOf(serverResponseCode);
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
}
}
This is the AsyncTask "Helpher" class used for upload image from Android. To call this class use like syntax below.
new Main2Activity.Helpher(this).execute(fileUri.getPath());
Here fileUri.getPath() local image location.
I took this code on Internet. I can upload image file to Server successful. However, the image files cannot be opened. I think the content of the files has problem after uploading. Can anybody help me please? Thank you very much
public static void put(String targetURL, File file, String username, String password) throws Exception {
String BOUNDRY = "==================================";
HttpURLConnection conn = null;
try {
// Make a connect to the server
URL url = new URL(targetURL);
conn = (HttpURLConnection) url.openConnection();
if (username != null) {
String usernamePassword = username + ":" + password;
//String encodedUsernamePassword = Base64.encodeBytes(usernamePassword.getBytes());
String encodedUsernamePassword = String.valueOf(Base64.encodeBase64(usernamePassword.getBytes()));
conn.setRequestProperty ("Authorization", "Basic " + encodedUsernamePassword);
}
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+BOUNDRY);
DataOutputStream dataOS = new DataOutputStream(conn.getOutputStream());
dataOS.writeBytes("--");
dataOS.writeBytes(BOUNDRY);
dataOS.writeBytes("\n");
dataOS.writeBytes("Content-Disposition: form-data; name=\"fileToUpload\"; fileName=\"" + file.getName() +"\"" + "\n");
dataOS.writeBytes("\n");
dataOS.writeBytes(new String(getBytesFromFile(file)));
dataOS.writeBytes("\n");
dataOS.writeBytes("--");
dataOS.writeBytes(BOUNDRY);
dataOS.writeBytes("--");
dataOS.writeBytes("\n");
dataOS.flush();
dataOS.close();
int responseCode = conn.getResponseCode();
if (responseCode != 200) {
throw new Exception(String.format("Received the response code %d from the URL %s", responseCode, url));
}
InputStream is = conn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[4096];
int bytesRead;
while((bytesRead = is.read(bytes)) != -1) {
baos.write(bytes, 0, bytesRead);
}
byte[] bytesReceived = baos.toByteArray();
baos.close();
is.close();
String response = new String(bytesReceived);
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead = is.read(bytes, offset, Math.min(bytes.length - offset, 512*1024))) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}
And the bellow is my code in PHP:
$target = "/upload/";
$target = $target . basename( $_FILES['fileToUpload']['name']) ;
if(move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $target)) {
echo "The file ". basename( $_FILES['fileToUpload']['name']). " has been uploaded";
$result['login'] = true;
}else {
$result['login']=false;
echo "Sorry, there was a problem uploading your file.";
}
$json = json_encode($result, JSON_PRETTY_PRINT);
print_r($json);
Maybe problem occur when you set Content-Type, try remove this
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+BOUNDRY);
I'm trying to encode a .jpg file on my server and send the string back to my android app. The PHP encoding function doesn't seem to be working - I always get a null response.
...
} else if ($tag == 'getPhoto') {
$filePath = $_POST['filePath'];
$filePath = mysql_real_escape_string($filePath);
$photo_str = $db->getPhotoString($filePath);
$photo_str = mysql_real_escape_string($photo_str);
if (!empty($photo_str)) {
echo $photo_str;
} else {
echo 'Something went wrong while retrieving the photo.';
}
}
...
public function getPhotoString($filePath) {
$type = pathinfo($filePath, PATHINFO_EXTENSION);
$photoData = file_get_contents($filePath);
$photo_str = 'data:image/' . $type . ';base64,' . base64_encode($photoData);
// $photo_str = 'test_response';
return $photo_str;
}
I know my filepath is correct because when I change it I get an error that says the file/directory doesn't exist. And, the "test_response" works when I uncomment it. Please help!
UPDATE - relevant android code:
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
HttpResponse response = httpClient.execute(httpPost);
photoString = convertResponseToString(response);
Log.d("string response", photoString);
public String convertResponseToString(HttpResponse response) throws IllegalStateException, IOException{
String res = "";
StringBuffer buffer = new StringBuffer();
is = response.getEntity().getContent();
int contentLength = (int) response.getEntity().getContentLength(); //getting content length…..
if (contentLength < 0) {
} else {
byte[] data = new byte[512];
int len = 0;
try {
while (-1 != (len = is.read(data))) {
buffer.append(new String(data, 0, len)); //converting to string and appending to stringbuffer…..
}
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close(); // closing the stream…..
} catch (IOException e) {
e.printStackTrace();
}
res = buffer.toString(); // converting stringbuffer to string…..
}
//System.out.println("Response => " + EntityUtils.toString(response.getEntity()));
return res;
}
This is not an answer, only a suggestion but i'm not able to comment as i don't have enough reputation xD. Anyway, did you try to echo $photoData after
$photoData = file_get_contents($filePath);
to see if it's filled with something? Maybe you get a null result. Also, can you tell me what's $filePath value when taken from $_POST variable and when passed to getPhotoString($filePath) function? I'm thinking about something wrong with mysql_real_escape_string().
So far I can send one set of data from Android to PHP web service. I'm hoping to send an array, and have a for loop in the web service. Is that possible? Is that a good solution? In this project, I'm trying to sync SQLite with MySQL.
Here's my code
String username, userid;
username = "Kate";
userid = "3";
String data = "";
try {
data = URLEncoder.encode("username", "UTF-8") + "="
+ URLEncoder.encode(username, "UTF-8");
data += "&" + URLEncoder.encode("userid", "UTF-8") + "="
+ URLEncoder.encode(userid, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String text = "";
BufferedReader reader = null;
try {
URL url = new URL(
address);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(
conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
reader = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
text = sb.toString();
} catch (Exception ex) {
} finally {
try {
reader.close();
} catch (Exception ex) { }
}
And this
<?php
include '../inc/connect.php';
include '../inc/class/mysql.class.php';
$name = urldecode($_POST['username']);
$user = urldecode($_POST['userid']);
print " ==== POST DATA =====
Name : $name
Email : $email
User : $user
Pass : $pass";
$ins = mysql_query("INSERT INTO users (UserName, FullName) VALUES ('$name','$user')") or die(mysql_error());
if ($ins) {
echo json_encode(array("result"=>"success","result_txt"=>"Branch sucessfully added."));
exit();
}
?>
You could send the input as JSON and then get PHP to decode it.
So you'd encode all your data in the android app and send it as one big encoded string, possibly using URI encoding or Base64, then in the PHP do:
$data = json_decode($_POST['data']);
If you use base64 then you'd do:
$data = json_decode(base64_decode($_POST['data']));
If you just send it as one string
$data = json_decode(urldecode($_POST['data']));