简体   繁体   English

如何将多个图像作为数据流从Android发送到WCF Rest Service以写入网络驱动器?

[英]How to send multiple images from android to a WCF Rest Service as a stream to write to a network drive?

After much googling and searching, I managed to send an image using multiparsers from android to my WCF service, but ideally, I'd like to send several images at once, instead of calling the method over and over again, since it'd take a lot longer, and add a bunch more overhead. 经过大量的搜索和搜索之后,我设法使用了多个解析器将图像从android发送到我的WCF服务,但理想情况下,我想一次发送多个图像,而不是一遍又一遍地调用该方法,因为它会更长的时间,并增加很多开销。

This is my current code 这是我当前的代码

Android (Taken from code found on here somewhere): Android(取自此处某处的代码):

public static String postFile(Bitmap bitmap, String urlString) throws Exception {

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(urlString);
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
    builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    ByteArrayOutputStream bao = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 30, bao);


    byte[] data = bao.toByteArray();


    //filename
    String fileName = String.format("File_%d.png",new Date().getTime());

    ByteArrayBody bab = new ByteArrayBody(data, fileName);


    builder.addPart("image", bab);
    final HttpEntity yourEntity = builder.build();

    class ProgressiveEntity implements HttpEntity {
        @Override
        public void consumeContent() throws IOException {
            yourEntity.consumeContent();                
        }
        @Override
        public InputStream getContent() throws IOException,
                IllegalStateException {
            return yourEntity.getContent();
        }
        @Override
        public Header getContentEncoding() {             
            return yourEntity.getContentEncoding();
        }
        @Override
        public long getContentLength() {
            return yourEntity.getContentLength();
        }
        @Override
        public Header getContentType() {
            return yourEntity.getContentType();
        }
        @Override
        public boolean isChunked() {             
            return yourEntity.isChunked();
        }
        @Override
        public boolean isRepeatable() {
            return yourEntity.isRepeatable();
        }
        @Override
        public boolean isStreaming() {             
            return yourEntity.isStreaming();
        } // CONSIDER put a _real_ delegator into here!

        @Override
        public void writeTo(OutputStream outstream) throws IOException {

            class ProxyOutputStream extends FilterOutputStream {
                /**
                 * @author Stephen Colebourne
                 */

                public ProxyOutputStream(OutputStream proxy) {
                    super(proxy);    
                }
                public void write(int idx) throws IOException {
                    out.write(idx);
                }
                public void write(byte[] bts) throws IOException {
                    out.write(bts);
                }
                public void write(byte[] bts, int st, int end) throws IOException {
                    out.write(bts, st, end);
                }
                public void flush() throws IOException {
                    out.flush();
                }
                public void close() throws IOException {
                    out.close();
                }
            } // CONSIDER import this class (and risk more Jar File Hell)

            class ProgressiveOutputStream extends ProxyOutputStream {
                public ProgressiveOutputStream(OutputStream proxy) {
                    super(proxy);
                }
                public void write(byte[] bts, int st, int end) throws IOException {

                    // FIXME  Put your progress bar stuff here!

                    out.write(bts, st, end);
                }
            }

            yourEntity.writeTo(new ProgressiveOutputStream(outstream));
        }

    };
    ProgressiveEntity myEntity = new ProgressiveEntity();

    post.setEntity(myEntity);
    HttpResponse response = client.execute(post);        

    return getContent(response);

} 

public static String getContent(HttpResponse response) throws IOException {
    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String body = "";
    String content = "";

    while ((body = rd.readLine()) != null) 
    {
        content += body + "\n";
    }
    return content.trim();
}

C# WCF Service method to take it C#WCF服务方法

[WebInvoke(UriTemplate = "UploadPicture/{filename}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    public String UploadPicture(string filename, Stream fileStream)
    {
        WriteLog("Uploading picture...");
        try
        {

            MultipartParser parser = new MultipartParser(fileStream);
            if (parser.Success)
            {
                string fileName = parser.Filename;
                string contentType = parser.ContentType;
                byte[] fileContent = parser.FileContents;
                FileStream fileToupload = new FileStream("\\\\OHS-SUN\\Tracker\\robbie\\" + filename, FileMode.Create);
                fileToupload.Write(fileContent, 0, fileContent.Length);
                fileToupload.Close();
                fileToupload.Dispose();
                fileStream.Close();
                return "Success !!!";
            }
            else
            {
                return "Exception!!!";
            }

        }
        catch (Exception ex)
        {
            WriteLog("Uploading picture exception: " + ex.Message);
        }

        return "Picture uploaded!";

    }      

I'd like to go from sending one image, to sending several, each with 2 text attributes; 我想从发送一张图片到发送几张图片,每张图片都有2个文本属性; the filename, and the project number they're associated with. 文件名以及与之关联的项目号。 Essentially, both is what I need it for. 本质上,两者都是我需要的。 At the moment, I'm just trying to do put another addPart on to the android bit, but then I don't know how to add metadata to that and I wouldn't know how to parse it based on the name. 此刻,我只是想将另一个addPart放在android位上,但是后来我不知道如何向其中添加元数据,也不知道如何根据名称解析它。 I'm fine with using any third party libraries, the one I'm using on C# at the moment is already one. 我可以使用任何第三方库,现在我在C#上使用的库已经是一个。

Thanks a lot! 非常感谢!

Instead of sending multiple images in one thing, I just stuck it in an asynchronous class and sent them concurrently with a max of 10 at a time until all the images are sent in that particular session. 而不是在一件事中发送多个图像,我只是将其卡在一个异步类中,并一次最多发送10个并发图像,直到在该特定会话中发送所有图像为止。 Seems to work fine, the implementation's the same, so I've not had to change any of that, which is good. 看起来工作正常,实现也一样,所以我不必更改任何一个,这很好。 If anyone would like me to post the code I did to do that, I'd be happy to. 如果有人希望我发布我这样做的代码,我将很高兴。 It's just small snippets here and there added to the above code, though. 不过,这只是上面的代码的小片段。

Well, the main bit I added was: 好吧,我添加的主要内容是:

public static class FileUploader extends AsyncTask<UploadFile , Void , String> implements Future<String>
{
    @Override
    protected void onPreExecute() {
        filesUploading ++;
    }

    @Override
    protected String doInBackground(UploadFile... uploadFile) 
    {
        try 
        {
            return postFile(uploadFile[0].file, uploadFile[0].projectNo, uploadFile[0].filename);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }               

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        filesUploading --;
    }

    @Override
    public boolean isDone() {
          return AsyncTask.Status.FINISHED == getStatus();
    }


}

This allows me to send each image separately, and handle them separately. 这使我可以分别发送每个图像,并分别处理它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM