3

我正在使用.net 4.0并尝试使用rest wcf服务上传文件,该服务使用名为upload的方法,并使用相同的rest服务使用名为download的方法下载文件。有一个控制台应用程序将流数据发送到 wcf 服务,并且从该服务下载相同的控制台应用程序。控制台应用程序使用 WebChannelFactory 连接并使用服务。

这是来自控制台应用程序的代码

            StreamReader fileContent = new StreamReader(fileToUpload, false);
            webChannelServiceImplementation.Upload(fileContent.BaseStream );

这是 wcf 服务代码

public void Upload(Stream fileStream)
{
        long filebuffer  = 0;
        while (fileStream.ReadByte()>0)
        {
            filebuffer++;
        }

        byte[] buffer = new byte[filebuffer];
        using (MemoryStream memoryStream = new MemoryStream())
        {
            int read;

            while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                memoryStream.Write(buffer, 0, read);

            }
            File.WriteAllBytes(path, buffer);
        }
}

现在,在我检查文件的这一步,我注意到它与从控制台应用程序发送的原始文件具有相同的千字节大小,但是当我打开文件时,它没有内容。该文件可以是任何文件类型,无论是 excel 还是 word 文档,它仍然以空文件的形式出现在服务器上。所有的数据都去哪儿了?

我这样做的原因fileStream.ReadByte()>0是因为我在某处读到,在通过网络传输时,找不到缓冲区长度(这就是为什么我在尝试在服务upload方法中获取流的长度时遇到异常的原因)。这就是为什么我不使用byte[] buffer = new byte[32768];许多在线示例中显示的字节数组是固定的。

从服务下载时,我在 wcf 服务端使用此代码

    public Stream Download()
    {
        return new MemoryStream(File.ReadAllBytes("filename"));
    }

在控制台应用程序方面,我有

        Stream fileStream = webChannelServiceImplementation.Download();

        //find size of buffer
        long size= 0;
        while (fileStream .ReadByte() > 0)
        {
            size++;
        }
        byte[] buffer = new byte[size];

        using (Stream memoryStream = new MemoryStream())
        {
            int read;
            while ((read = fileContents.Read(buffer, 0, buffer.Length)) > 0)
            {
                memoryStream.Write(buffer, 0, read);
            }

            File.WriteAllBytes("filename.doc", buffer);
        }

现在这个下载的文件也是空白的,因为它下载了我之前使用上面的上传代码上传的文件,即使上传的文件大小为 200 KB,它的大小也只有 16 KB。

我的代码有什么问题?任何帮助表示赞赏。

4

2 回答 2

3

你可以让这更简单:

public void Upload(Stream fileStream)
{
    using (var output = File.Open(path, FileMode.Create))
        fileStream.CopyTo(output);
}

您现有代码的问题是您调用ReadByte并读取了整个输入流,然后尝试再次读取它(但现在已经结束了)。这意味着您的第二次读取将全部失败(read变量将在您的循环中为 0,并立即中断),因为流现在已结束。

于 2013-10-14T16:09:25.923 回答
2

在这里,我创建了一个 WCF REST 服务。 服务.svc.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace UploadSvc
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
                 InstanceContextMode = InstanceContextMode.PerCall,
                 IgnoreExtensionDataObject = true,
                 IncludeExceptionDetailInFaults = true)]    
      public class UploadService : IUploadService
    {

        public UploadedFile Upload(Stream uploading)
        {
            var upload = new UploadedFile
            {
                FilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())
            };

            int length = 0;
            using (var writer = new FileStream(upload.FilePath, FileMode.Create))
            {
                int readCount;
                var buffer = new byte[8192];
                while ((readCount = uploading.Read(buffer, 0, buffer.Length)) != 0)
                {
                    writer.Write(buffer, 0, readCount);
                    length += readCount;
                }
            }

            upload.FileLength = length;

            return upload;
        }

        public UploadedFile Upload(UploadedFile uploading, string fileName)
        {
            uploading.FileName = fileName;
            return uploading;
        }
    }
}

网页配置

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpRuntime executionTimeout="100000" maxRequestLength="20000000"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 maxReceivedMessageSize="2147483647"
                 transferMode="Streamed"
                 sendTimeout="00:05:00" closeTimeout="00:05:00" receiveTimeout="00:05:00">
          <readerQuotas  maxDepth="2147483647"
                         maxStringContentLength="2147483647"
                         maxArrayLength="2147483647"
                         maxBytesPerRead="2147483647"
                         maxNameTableCharCount="2147483647"/>
          <security mode="None" />
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="defaultEndpointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="defaultServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="UploadSvc.UploadService" behaviorConfiguration="defaultServiceBehavior">
        <endpoint address="" behaviorConfiguration="defaultEndpointBehavior"
          binding="webHttpBinding" contract="UploadSvc.IUploadService"/>
      </service>
    </services>    
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

消费者.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Text;

namespace UploadSvcConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            //WebClient client = new WebClient();
            //client.UploadData("http://localhost:1208/UploadService.svc/Upload",)
            //string path = Path.GetFullPath(".");
            byte[] bytearray=null ;
            //throw new NotImplementedException();
            Stream stream =
                new FileStream(
                    @"C:\Image\hanuman.jpg"
                    FileMode.Open);
                stream.Seek(0, SeekOrigin.Begin);
                bytearray = new byte[stream.Length];
                int count = 0;
                while (count < stream.Length)
                {
                    bytearray[count++] = Convert.ToByte(stream.ReadByte());
                }

            string baseAddress = "http://localhost:1208/UploadService.svc/";
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "Upload");
            request.Method = "POST";
            request.ContentType = "text/plain";
            request.KeepAlive = false;
            request.ProtocolVersion = HttpVersion.Version10;
            Stream serverStream = request.GetRequestStream();
            serverStream.Write(bytearray, 0, bytearray.Length);
            serverStream.Close();
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                int statusCode = (int)response.StatusCode;
                StreamReader reader = new StreamReader(response.GetResponseStream());

            }

        }
    }
}
于 2014-05-26T18:44:46.830 回答