ASP.NET、JAVA跨服务器远程上传文件(图片)的相关解决方案整合

一、图片提交例:

A端--提交图片

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string url = "http://www./AppWeb/AppService.asmx";
string method = "test";
string result1 = BuildRequest(url + "/" + method, System.Web.HttpContext.Current.Server.MapPath("~/images/") + "1.png", "UTF-8");
Response.Write(result1);
}
}
public static string BuildRequest(string strUrl, string strPicPath, string _input_charset)
{
Encoding code = Encoding.GetEncoding(_input_charset); //把数组转换成流中所需字节数组类型
byte[] bytesRequestData = SetImgToByte(strPicPath); //请求远程HTTP
string strResult = "";
try
{
//设置HttpWebRequest基本信息
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
myReq.Method = "post";
myReq.ContentType = "application/x-www-form-urlencoded"; //填充POST数据
myReq.ContentLength = bytesRequestData.Length;
Stream requestStream = myReq.GetRequestStream();
requestStream.Write(bytesRequestData, , bytesRequestData.Length);
requestStream.Close(); //发送POST数据请求服务器
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream(); //获取服务器返回信息
StreamReader reader = new StreamReader(myStream, code);
StringBuilder responseData = new StringBuilder();
String line;
while ((line = reader.ReadLine()) != null)
{
responseData.Append(line);
} //释放
myStream.Close(); strResult = responseData.ToString();
}
catch (Exception exp)
{
strResult = "报错:" + exp.Message;
} return strResult;
}
/// <summary>
/// 将图片转化为长二进制
/// </summary>
/// <param name="photopath"></param>
/// <returns></returns>
public static Byte[] SetImgToByte(string imgPath)
{
FileStream file = new FileStream(imgPath, FileMode.Open, FileAccess.Read);
Byte[] byteData = new Byte[file.Length];
file.Read(byteData, , byteData.Length);
file.Close();
return byteData;
}

B端--接收图片

[WebMethod(Description = "test")]
public string test()
{
if ("POST" == System.Web.HttpContext.Current.Request.RequestType)
{
System.IO.Stream sm = System.Web.HttpContext.Current.Request.InputStream;//获取post正文
int len = (int)sm.Length;//post数据长度
byte[] inputByts = new byte[len];//字节数据,用于存储post数据
sm.Read(inputByts, , len);//将post数据写入byte数组中
sm.Close();//关闭IO流
string fileName = Guid.NewGuid() + ".jpg";
string strPath = System.Web.HttpContext.Current.Server.MapPath("~/images/") + fileName;
//此处还需要做文件类型的判断
using (FileStream fileStream = new FileStream(strPath, FileMode.Create))
{
fileStream.Write(inputByts, , inputByts.Length);
} return "";
}
return "";
}

二、

1.通过FTP来上传文件

首先,在另外一台服务器上设置好FTP服务,并创建好允许上传的用户和密码,然后,在ASP.NET里就可以直接将文件上传到这台 FTP 服务器上了。代码如下:

<%@ Page Language="C#" EnableViewState="false"%>

<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.IO" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
//要接收文件的 ftp 服务器地址
String serverUri = "ftp://192.168.3.1/";
String fileName = Path.GetFileName(FileUpload1.FileName);
serverUri += fileName; FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.AppendFile;
request.UseBinary = true;
request.UsePassive = true; // ftp 服务器上允许上传的用户名和密码
request.Credentials = new NetworkCredential("upload", "upload");
Stream requestStream = request.GetRequestStream();
Byte[] buffer = FileUpload1.FileBytes; requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Label1.Text = response.StatusDescription;
response.Close();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>将文件上传到另外一个服务器的方法二</title>
</head>
<body>
<form id="form1" runat="server">
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="上传文件" />
<div><asp:Label ID="Label1" runat="server" Text=""></asp:Label></div>
</form>
</body>
</html>

2.通过WebClient来上传文件

如:现在的开发的web应用程序的虚拟目录是WebAA,另一个应用程序的虚拟目录是WebBB,现在要从WebAA向WebBB下的一个UpLoadFiles文件夹下保存图片

在WebBB项目下添加一个UploadHandler.ashx文件,代码如下:

public class UploadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string filename = context.Request.QueryString["filename"].ToString();
using (FileStream inputStram = File.Create(context.Server.MapPath("UpLoadFiles/") + filename))
{
SaveFile(context.Request.InputStream, inputStram);
} }
protected void SaveFile(Stream stream, FileStream inputStream)
{
int bufSize=;
int byteGet=;
byte[] buf=new byte[bufSize];
while ((byteGet = stream.Read(buf, , bufSize)) > )
{
inputStream.Write(buf, , byteGet);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}

在WebAA项目中通过WebClient或者WebRequest请求该url,下面以WebClient为例说明。 在WebAA中新建test.aspx页面,上面有FileUpload控件FileUpload1和Button控件Button1,具体事件代码如 下:

using System.IO;
using System.Net; MemoryStream ms;
protected void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
int bufSize = ;
int byteGet = ;
byte[] buf = new byte[bufSize];
while ((byteGet = ms.Read(buf, , bufSize)) > )//循环读取,上传
{
e.Result.Write(buf, , byteGet);//注意这里
}
e.Result.Close();//关闭
ms.Close();关闭ms
}
protected void Button1_Click(object sender, EventArgs e)
{
FileUpload fi = FileUpload1; byte[] bt = fi.FileBytes;//获取文件的Byte[]
ms = new MemoryStream(bt);//用Byte[],实例化ms UriBuilder url = new UriBuilder("http://xxxxxxxx/WebBB/UploadHandler.ashx");//上传路径
url.Query = string.Format("filename={0}", Path.GetFileName(fi.FileName));//上传url参数
WebClient wc = new WebClient();
wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);//委托异步上传事件
wc.OpenWriteAsync(url.Uri);//开始异步上传
}

3.通过Web Service来上传文件(与第二种其实原理有些相同)

首先定义Web Service类,代码如下:

using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.IO; namespace UpDownFile
{
/**/
/// <summary>
/// UpDownFile 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class UpDownFile : System.Web.Services.WebService
{
//上传文件至WebService所在服务器的方法,这里为了操作方法,文件都保存在UpDownFile服务所在文件夹下的File目录中
[WebMethod]
public bool Up(byte[] data, string filename)
{
try
{
FileStream fs = File.Create(Server.MapPath("File/") + filename);
fs.Write(data, , data.Length);
fs.Close();
return true;
}
catch
{
return false;
}
} //下载WebService所在服务器上的文件的方法
[WebMethod]
public byte[] Down(string filename)
{
string filepath = Server.MapPath("File/") + filename;
if (File.Exists(filepath))
{
try
{
FileStream s = File.OpenRead(filepath);
return ConvertStreamToByteBuffer(s);
}
catch
{
return new byte[];
}
}
else
{
return new byte[];
}
}
}
}

在网站中引用上述创建的WEB服务,命名为(UpDownFile,可自行定义),然后在页面DownFile.aspx中分别实现文件上传与下载:

//上传:

            //FileUpload1是aspx页面的一个FileUpload控件
UpDownFile.UpDownFile up = new UpDownFile.UpDownFile();
up.Up(ConvertStreamToByteBuffer(FileUpload1.PostedFile.InputStream),
FileUpload1.PostedFile.FileName.Substring(FileUpload1.PostedFile.FileName.LastIndexOf("\\") + )); //下载:
UpDownFile.UpDownFile down = new UpDownFile.UpDownFile();
byte[] file = down.Down(Request.QueryString["filename"].ToString()); //filename是要下载的文件路径,可自行以其它方式获取文件路径
Response.BinaryWrite(file); //以下是将文件流转换成文件字节的函数(因为Stream类型的是不能直接通过WebService传输):
protected byte[] ConvertStreamToByteBuffer(Stream s)
{
BinaryReader br = new BinaryReader(stream);
byte[] fileBytes = br.ReadBytes((int)stream.Length);
return fileBytes;
}

4.通过页面跳转或嵌套页面的方式(这种方法很简单,严格不算跨服务器,且有一定的局限性)

实现方法:

1.在需要上传文件的页面加入iframe,iframe的地址指向另一个服务器上传页面,并且页面需包含上传按钮;
.需要上传时就利用JS的location.href或服务端的Response.redirect跳转至另一个服务器上传页面;

方法其实还有多很,这里就不一一例举,当然上述方法只是实现上传与下载功能,有时可能还需考虑跨服务器删除文件,这个可能需要考虑安全等方面的问题。

三、

跨服务器上传,利用B.com的handler文件,先将文件进行编码,使用POST方式传递到handler,然后handler将文件保存到服务器上,同时返回相应的结果。
将文件转为Base64:

string fileName = FileUpload.FileName;
FileInfo file = new FileInfo(fileName);
string ext=file.Extension;
Stream stream = FileUpload.PostedFile.InputStream;
BinaryReader br = new BinaryReader(stream);
byte[] fileByte = br.ReadBytes((int)stream.Length);
string baseFileString = Convert.ToBase64String(fileByte);

在handler.ashx中做处理:

/// <summary>
/// 上传图片
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class CrossServerFileUpload : IHttpHandler
{
private string _allowFileTypes = "gif,jpg,jpeg,png,bmp"; private HttpContext _context;
public void ProcessRequest(HttpContext context)
{
_context = context; string src = context.Request.Form["src"];
if (string.IsNullOrEmpty(src)) return; src = src.ToLower();
bool isExtValid = src.EndsWith(".jpg") || src.EndsWith(".png") || src.EndsWith(".gif") || src.EndsWith(".bmp") || src.EndsWith(".jpeg");
if (isExtValid) {
context.Response.ContentType = "text/plain";
string ext = context.Request.Form["ext"];
string content = context.Request.Form["data"]; Upload(ext, content);
}
}
/// <summary>
/// 上传类
/// </summary>
/// <param name="ext"></param>
/// <param name="content"></param>
private void Upload(string ext,string content)
{
if (string.IsNullOrEmpty(ext) || string.IsNullOrEmpty(content)) {
return;
}
//保存图片
string dateNum = DateTime.Now.ToString("yyyyMM");//按月存放
string fileName = Guid.NewGuid() + ext;
string currentPath = HttpContext.Current.Request.PhysicalApplicationPath + "upload\\" + dateNum + "\\";
string fullPath =currentPath + fileName; if (!Directory.Exists(currentPath))
Directory.CreateDirectory(currentPath); byte[] buffer = Convert.FromBase64String(content);
using (FileStream fileStream = new FileStream(fullPath, FileMode.Create)) {
fileStream.Write(buffer, , buffer.Length);
}
string host = _context.Request.Url.Host;
ResponseWrite(string.Format("http://" + host + "/upload/{0}/{1}", dateNum, fileName));//返回图片保存路径
}
/// <summary>
/// 生成http内容
/// </summary>
/// <param name="content"></param>
private void ResponseWrite(string content)
{
_context.Response.ClearContent();
_context.Response.ContentType = "text/plain";
_context.Response.Write(content);
_context.Response.End();
}

以上是跨服务器处理代码的核心代码,实际应用中还需要考虑权限问题。

四、可以根据方法一 ,把二进制与字符串转换,在进行传输,这样更方便 加入 文字内容或多文件一起上传(图片转换)

C#

//将二进制文件转为Base64
string baseFileString = Convert.ToBase64String(fileByte);
//将Base64转为二进制文件
byte[] buffer = Convert.FromBase64String(content);

Server端

string strFile = list.imgContent;
//将图片字符串转化为2进制数组
System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
byte[] byteImg = converter.GetBytes(strFile);
//将图片的二进制数据转化为图片
System.IO.MemoryStream ms = new System.IO.MemoryStream(byteImg);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
string strSavePath = Server.MapPath("~") + "\\images\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
img.Save(strSavePath, System.Drawing.Imaging.ImageFormat.Bmp);

二进制与字符串转换--JAVA代码

public class Test{
public static void main(String[] args) {
try{ // 将图片转换成字符串
File f = new File("c:\\biao.png");
FileInputStream fis = new FileInputStream( f );
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
fis.close(); // 生成字符串
String imgStr = byte2hex( bytes );
System.out.println( imgStr); // 将字符串转换成二进制,用于显示图片
// 将上面生成的图片格式字符串 imgStr,还原成图片显示
OutputStream o = new FileOutputStream("c:\\878789.png");
byte[] imgByte = hex2byte( imgStr );
InputStream in = new ByteArrayInputStream( imgByte );
byte[] b = new byte[1024];
int nRead = 0;
while( ( nRead = in.read(b) ) != -1 ){
o.write( b, 0, nRead );
}
o.flush();
o.close();
in.close(); }catch(Exception e){
e.printStackTrace();
}finally{
}
}
/**
* 二进制转字符串
* @param b byte数组
* @return 二进制字符串
*/
public static String byte2hex(byte[] b){
StringBuffer sb = new StringBuffer();
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1) {
sb.append("0" + stmp);
} else {
sb.append(stmp);
}
}
return sb.toString();
}
/**
* 字符串转二进制
* @param str 字符串
* @return byte数组
*/
public static byte[] hex2byte(String str) {
if (str == null)
return null;
str = str.trim();
int len = str.length();
if (len == 0 || len % 2 == 1)
return null;
byte[] b = new byte[len / 2];
try {
for (int i = 0; i < str.length(); i += 2) {
b[i / 2] = (byte) Integer.decode("0X" + str.substring(i, i + 2)).intValue();
}
return b;
} catch (Exception e) {
return null;
}
}
}

五、上传

private void button1_Click(object sender, System.EventArgs e)
{
WebClient myWebClient = new WebClient();
myWebClient.UploadFile("http://localhost/UploadFileWeb/WebForm1.aspx","POST",@"D:\Temp\Java\JavaStart\JavaStart2.exe");
}

六、其它案例详解C#

http://blog.csdn.net/wangxiaona356/article/details/6753986

七、JAVA经典案例

1.安卓客户端JAVA上传文件到JAVA网站 https://github.com/kk-java/UploadFile

2.安卓客户端JAVA上传文件到ASP.NET网站http://www.codicode.com/art/upload_files_from_android_to_a_w.aspx

3.安卓客户端JAVA上传文件到JAVA网站http://www.cnblogs.com/gzggyy/archive/2011/08/02/2125237.html

https://github.com/kk-java/UploadFile

上一篇:双机冗余备份和负载均衡策略(Mysql Cluster入门安装配置指南)


下一篇:MAC OX 配置JDK环境变量