首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HttpServer - HttpExchange - Seekable流

HttpServer - HttpExchange - Seekable流
EN

Stack Overflow用户
提问于 2013-08-05 15:35:23
回答 1查看 3.1K关注 0票数 0

我在一个样例java http服务器和一个.Net客户机上工作(在平板电脑上)。使用我的http服务器,.Net客户端必须能够下载文件。

它工作得很好,但是现在我必须能够在连接中断后恢复下载。

这里有一些代码:

Java服务器: (它是在一个独立的线程中启动的,因此是run方法)。

代码语言:javascript
复制
public void run() {

    try {
        server = com.sun.net.httpserver.HttpServer.create(
                new InetSocketAddress(
                        portNumber), this.maximumConnexion);

        server.setExecutor(executor);
        server.createContext("/", new ConnectionHandler(this.rootPath));
        server.start();


    } catch (IOException e1) {
        //For debugging
        e1.printStackTrace();
    }

}

my HttpHandler : (只处理GET请求的部分)

代码语言:javascript
复制
/**
 * handleGetMethod : handle GET request. If the file specified in the URI is
 * available, send it to the client.
 * 
 * @param httpExchange
 * @throws IOException
 */
private void handleGetMethod(HttpExchange httpExchange) throws IOException {

File file = new File(this.rootPath + this.fileRef).getCanonicalFile();

if (!file.isFile()) {
    this.handleError(httpExchange, 404);
} else if (!file.getPath().startsWith(this.rootPath.replace('/', '\\'))) { // windows work with anti-slash!
    // Suspected path traversal attack.
    System.out.println(file.getPath());
    this.handleError(httpExchange, 403);
} else {
    //Send the document.


    httpExchange.sendResponseHeaders(200, file.length());       
    System.out.println("file length : "+ file.length() + " bytes.");


    OutputStream os = httpExchange.getResponseBody();

    FileInputStream fs = new FileInputStream(file);

    final byte[] buffer = new byte[1024];
    int count = 0;
    while ((count = fs.read(buffer)) >= 0) {
        os.write(buffer, 0, count);
    }
    os.flush();
    fs.close();
    os.close();
}

}

,现在是我的.Net客户机:(简化)

代码语言:javascript
复制
  try{

        Stream response = await httpClient.GetStreamAsync(URI + this.fileToDownload.Text);


    FileSavePicker savePicker = new FileSavePicker();
    savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
    // Dropdown of file types the user can save the file as
    savePicker.FileTypeChoices.Add("Application/pdf", new List<string>() { ".pdf" });
    // Default file name if the user does not type one in or select a file to replace
    savePicker.SuggestedFileName = "new doc";

    StorageFile file = await savePicker.PickSaveFileAsync();

    if (file != null)
    {

        const int BUFFER_SIZE = 1024*1024;
        using (Stream outputFileStream = await file.OpenStreamForWriteAsync())
        {
            using (response)
            {
                var buffer = new byte[BUFFER_SIZE];
                int bytesRead;                          
                do
                {
                    bytesRead = response.Read(buffer, 0, BUFFER_SIZE);
                    outputFileStream.Write(buffer, 0, bytesRead);                                
                } while (bytesRead > 0);
            } 
            outputFileStream.Flush();
       }

   }

}
catch (HttpRequestException hre)
{   //For debugging
    this.Display.Text += hre.Message;
    this.Display.Text += hre.Source;
}
catch (Exception ex)
{
    //For debugging
    this.Display.Text += ex.Message;
    this.Display.Text += ex.Source;
}

因此,为了恢复下载,我想在.Net客户端部分中使用一些查找操作。但是,每次我尝试类似于response.Seek(offset, response.Position);的操作时,都会发生错误,通知流不支持搜索操作。是的,它没有,但我如何指定(在我的服务器端)使用可查找流?HttpExchange.setStreams方法有用吗?或者,我不需要修改流,而是配置我的HttpServer实例?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-06 15:18:18

良好的使用范围,接受范围和内容范围领域的工作。为了发送文件的正确部分和设置响应的头部,只需做一些工作。

服务器可以通过设置Accept-Range字段通知客户端它支持Range字段:

代码语言:javascript
复制
responseHeader.set("Accept-Ranges", "bytes");

然后,在发送部分文件时设置内容范围字段:

代码语言:javascript
复制
responseHeader.set("Content-range", "bytes " + this.offSet + "-" + this.range + "/" + this.fileLength);

最后,返回代码必须设置为206 (部分内容)。

有关范围、接受范围和内容范围字段的详细信息,请参阅http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

注: Opera 12.16使用字段“范围”恢复下载,但IE10和Firefox 22似乎不使用此字段。可能是一些可寻觅的溪流,因为我原来是寻找。如果有人对此有答案的话,我很乐意读到。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18062088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档