日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

任意java程序都可以是servlet吗_C#从Java servlet中获取文件流实现任意文件下载

發布時間:2024/1/23 C# 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 任意java程序都可以是servlet吗_C#从Java servlet中获取文件流实现任意文件下载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目的:

從C#創建的客戶端中向Java創建的servlet提交請求(不知道這是否算作嚴格的CS架構),servet返回一個文件流( 任意格式的文件 ),然后通過C#獲取該文件流并保存到本地,使得文件可以正常打開并完整無缺。

發現問題:

Java中的servlet代碼如下:

package servlet;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.*;

@WebServlet(urlPatterns = "/update")

public class getUpdate extends HttpServlet{

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// super.doGet(req, resp);

File file=new File("D:\\test.exe");

FileInputStream inputStream=new FileInputStream(file);

int i=inputStream.available();

byte[] data=new byte[i];

inputStream.read(data);

ServletOutputStream outputStream=resp.getOutputStream();

outputStream.write(data);

outputStream.flush();

outputStream.close();

inputStream.close();

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

super.doPost(req, resp);

}

}

servlet的環境為本地,D盤下的test.exe是一個可執行的winform程序,用于文件的完整性測試。

將以上代碼部署到tomcat后,直接在瀏覽器中輸入“http://localhost:8080/update”可以下載到名為update的文件,給update添加.exe后綴后直接打開發現可以正常執行,這表明該servlet并沒什么問題。

客戶端的C#代碼如下:

using System;

using System.IO;

using System.Net;

namespace ServiceTest

{

class Program

{

static void Main(string[] args)

{

string url = "http://localhost:8080/update";

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);

WebResponse webResponse = webRequest.GetResponse();

Stream responseStream = webResponse.GetResponseStream();

FileStream fileStream = new FileStream("test.exe", FileMode.Create);

byte[] data = new byte[100000];

int count = responseStream.Read(data, 0, data.Length);

fileStream.Write(data, 0, count);

Console.WriteLine("OK");

fileStream.Close();

responseStream.Close();

}

}

}

剛開始我覺得test.exe文件不過只有15kb,這里給出的byte[100000]一定綽綽有余。所以當我執行程序時,發現控制臺可以正常輸出“OK”,但是在該項目目錄下的test.exe文件卻只有8kb:

test.exe屬性

而且很明顯,雙擊該文件無法執行:

test.exe執行結果

解決問題:

然后我用Java寫了個測試代碼:

package test;

import java.io.*;

import java.net.HttpURLConnection;

import java.net.URL;

import java.net.URLConnection;

public class Test2 {

public static void main(String[] args) {

String url = "http://localhost:8080/update";

try {

URLConnection connection = new URL(url).openConnection();

HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

InputStream inputStream = httpURLConnection.getInputStream();

int i = inputStream.available();

byte[] data = new byte[i];

inputStream.read(data);

File file = new File("D:\\test2.exe");

OutputStream outputStream = new FileOutputStream(file);

outputStream.write(data);

System.out.println("finish");

outputStream.close();

inputStream.close();

httpURLConnection.disconnect();

((HttpURLConnection) connection).disconnect();

} catch (Exception e) {

e.printStackTrace();

}

}

}

運行后得到的test2.exe文件完全正常!

于是接下來分別對C#客戶端代碼和Java客戶端代碼進行調試:

C#調試

Java調試

從上面兩張圖可以看出data內容不盡相同,在C#中data[2]=144,但是在Java中data[2]=-112。原因是C#中的byte取值為0~255,而Java中的byte取值為-128~127。但這好像不是問題的關鍵,關鍵是在C#中的8192行以后,數據全部為空,到此截斷。

C#調試

掐指一算,8192/1024=8。這時才明白new byte[100000]的寫法是錯誤的,而且是及其荒謬可笑的不符合程序員思想的不能容忍的應當被槍斃的錯誤!

修正后的C#關鍵代碼如下:

byte[] data = new byte[1024];

int count;

while ((count = responseStream.Read(data, 0, data.Length)) != 0)

{

fileStream.Write(data, 0, count);

}

同時意識到servlet中的寫法也是不負責任的,當要傳輸的文件過大時,問題就會顯現出來,因此修改后的servlet關鍵代碼如下:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

File file=new File("D:\\test.exe");

FileInputStream inputStream=new FileInputStream(file);

ServletOutputStream outputStream=resp.getOutputStream();

byte[] data=new byte[1024];

int count;

while ((count=inputStream.read(data,0,data.length))!=-1){

outputStream.write(data,0,count);

}

outputStream.flush();

outputStream.close();

inputStream.close();

}

總結:

1.C#中的byte是無符號的,取值范圍為0~255;而Java中的byte是有符號的,取值范圍為-128~127。

2.C#中的byte[]最多只到8192,即8k,超出8192部分不會被存取。Java雖然沒有此限制,但是直接new一個長度很長的數組去保存文件流信息仍是極其不推薦的。

3.C#中public abstract int Read(byte[] buffer, int offset, int count)函數當讀取到文件結尾時返回值為0;而Java中public int read(byte b[], int off, int len)返回值為-1。

4.C#中的StreamReader和StreamWriter只適合讀寫字符串,而不能用于處理二進制文件。

總結

以上是生活随笔為你收集整理的任意java程序都可以是servlet吗_C#从Java servlet中获取文件流实现任意文件下载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。