C# 为什么从硬盘上的ftp服务器下载文件时会看到100???.jpg?
首先,这是我硬盘上的原始文件名:שקל100.jpg שקל是希伯来语中的一个词 将文件上载到ftp时,上载没有问题,但ftp服务器上的文件名如下所示: ftp服务器上的文件看起来像是gibrish而不是希伯来语。 问题是当我试图下载文件时。文件名为100???.jpg 而FtpWebrequest不知道什么是100???.jpgC# 为什么从硬盘上的ftp服务器下载文件时会看到100???.jpg?,c#,.net,winforms,file-upload,ftp,C#,.net,Winforms,File Upload,Ftp,首先,这是我硬盘上的原始文件名:שקל100.jpg שקל是希伯来语中的一个词 将文件上载到ftp时,上载没有问题,但ftp服务器上的文件名如下所示: ftp服务器上的文件看起来像是gibrish而不是希伯来语。 问题是当我试图下载文件时。文件名为100???.jpg 而FtpWebrequest不知道什么是100???.jpg reqFTP = (FtpWebRequest)FtpWebRequest.Create(fileurl); 在fileurl中,我看到: 问题是在这种情况下我能
reqFTP = (FtpWebRequest)FtpWebRequest.Create(fileurl);
在fileurl中,我看到:
问题是在这种情况下我能做什么?也许要强制将文件名重新命名为某个默认的临时文件名
我想问题是ftp服务器ipage.com主机不知道如何阅读希伯来语,所以上传后看起来像吉卜里语
或者我需要上传它,用希伯来语编码文件名?
这是我用来上传文件的方法:
private void StringArrayUploadFiles(object sender, DoWorkEventArgs e)
{
try
{
UploadedFiles = files;
foreach (string fn in files)
{
BackgroundWorker bw = sender as BackgroundWorker;
f = e.Argument as FtpSettings;
MakeDir(f.TargetFolder);
string UploadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(fn));
if (!UploadPath.ToLower().StartsWith("ftp://"))
UploadPath = "ftp://" + UploadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(UploadPath);
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = 300000;
request.Credentials = new NetworkCredential(f.Username, f.Password);
long FileSize = new FileInfo(fn).Length;//f.SourceFile).Length;
string FileSizeDescription = GetFileSize(FileSize);
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
long SentBytes = 0;
byte[] Buffer = new byte[ChunkSize];
using (Stream requestStream = request.GetRequestStream())
{
using (FileStream fs = File.Open(fn, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
int BytesRead = fs.Read(Buffer, 0, ChunkSize);
while (BytesRead > 0)
{
try
{
if (bw.CancellationPending)
return;
requestStream.Write(Buffer, 0, BytesRead);
SentBytes += BytesRead;
string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(SentBytes), FileSizeDescription);
bw.ReportProgress((int)(((decimal)SentBytes / (decimal)FileSize) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
fs.Position -= BytesRead;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
BytesRead = fs.Read(Buffer, 0, ChunkSize);
}
}
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("Upload File Complete, status {0}", response.StatusDescription));
}
//}
}
catch (WebException ex)
{
switch (ex.Status)
{
case WebExceptionStatus.NameResolutionFailure:
ConnectionError = "Error: Please check the ftp address";
break;
case WebExceptionStatus.Timeout:
ConnectionError = "Error: Timout Request";
break;
}
}
}
private void stringarrayuploaddfiles(对象发送方,DoWorkEventArgs e)
{
尝试
{
UploadedFiles=文件;
foreach(文件中的字符串fn)
{
BackgroundWorker bw=发送方作为BackgroundWorker;
f=e.作为FTP设置的参数;
MakeDir(f.TargetFolder);
string UploadPath=string.Format(“{0}/{1}{2}”,f.Host,f.TargetFolder==”?“”:f.TargetFolder+“/”,Path.GetFileName(fn));
如果(!UploadPath.ToLower().StartsWith(“ftp:/”))
UploadPath=“ftp://”+UploadPath;
FtpWebRequest=(FtpWebRequest)WebRequest.Create(UploadPath);
request.UseBinary=true;
request.use被动=f.被动;
request.Method=WebRequestMethods.Ftp.UploadFile;
请求超时=300000;
request.Credentials=新的网络凭据(f.用户名,f.密码);
long FileSize=new FileInfo(fn).Length;//f.SourceFile).Length;
字符串FileSizeDescription=GetFileSize(FileSize);
int ChunkSize=4096,NumRetries=0,MaxRetries=50;
长SentBytes=0;
字节[]缓冲区=新字节[ChunkSize];
使用(Stream requestStream=request.GetRequestStream())
{
使用(FileStream fs=File.Open(fn,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
int BytesRead=fs.Read(缓冲区,0,ChunkSize);
而(字节读取>0)
{
尝试
{
if(bw.取消挂起)
返回;
写入(缓冲区,0,字节读取);
SentBytes+=字节读取;
string SummaryText=string.Format(“传输的{0}/{1}”、GetFileSize(SentBytes)、FileSizeDescription);
bw.ReportProgress((int)((十进制)SentBytes/(十进制)文件大小)*100),SummaryText);
}
捕获(例外情况除外)
{
Debug.WriteLine(“异常:+ex.ToString());
if(NumRetries++
我现在做了一个测试,试图上传一个文件名为希伯来语的文件。
在变量文件中,我看到了带有希伯来文字母的文件。
并且上传的文件没有任何异常或问题
这就是文件再次使用gibrish上传后在ftp服务器上的外观:
我能为这种情况做些什么?在上传之前做编码的上传方法应该解决吗?如果是这样的话,我如何进行编码?这可能很简单,只需更改FTP服务器,或切换到SFTP即可 如果兼容RFC 2640的客户端在上发送OPTS UTF-8,则无论OPTS UTF-8 ON是否成功,它都必须使用UTF-8。RFC 2640兼容服务器不得使UTF-8依赖于上的OPTS UTF-8 如果这不是一个选项,那么在这种情况下,恐怕您必须自己执行文件名编码和解码
const string fileName = "100%ץצקרתﬤﬢ.jpg";
var bytes = Encoding.Unicode.GetBytes(fileName);
var doubleBytes = bytes.ToObservable().Buffer(2);
var asciiFileName = new StringBuilder();
doubleBytes.Subscribe(
s =>
asciiFileName.Append(s[1] == 0
? (s[0] == 37 ? "%25" : Convert.ToString((char) s[0]))
: String.Format("%{0:X2}%{1:X2}", s[0], s[1]).PadLeft(2, '0')));
在这里,我完全懒得依靠反应式扩展来为我缓冲数据
asciiFileName的值将
100%25%E5%05%E6%05%E7%05%E8%05%EA%05%24%FB%22%FB.jpg
public static class Extensions
{
public static IEnumerable<byte[]> ToBytePairs(this byte[] array)
{
var enumerator = array.GetEnumerator();
while (enumerator.MoveNext())
{
var bytePair = new byte[2];
bytePair[0] = (byte)enumerator.Current;
enumerator.MoveNext();
bytePair[1] = (byte)enumerator.Current;
yield return bytePair;
}
}
}
#region
using System;
using System.IO;
using System.Net;
using System.Threading;
#endregion
namespace FtpUnicodeClient
{
public class FtpState
{
private readonly ManualResetEvent _wait;
public FtpState()
{
OperationException = null;
_wait = new ManualResetEvent(false);
}
public ManualResetEvent OperationComplete
{
get { return _wait; }
}
public FtpWebRequest Request { get; set; }
public string FileName { get; set; }
public Exception OperationException { get; set; }
public string StatusDescription { get; set; }
}
public class AsynchronousFtpUpLoader
{
// Command line arguments are two strings:
// 1. The url that is the name of the file being uploaded to the server.
// 2. The name of the file on the local machine.
//
public static void Main(string[] args)
{
// Create a Uri instance with the specified URI string.
// If the URI is not correctly formed, the Uri constructor
// will throw an exception.
var target = new Uri(args[0]);
string fileName = args[1];
var state = new FtpState();
var request = (FtpWebRequest) WebRequest.Create(target + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example uses anonymous logon.
// The request is anonymous by default; the credential does not have to be specified.
// The example specifies the credential only to
// control how actions are logged on the server.
request.Credentials = new NetworkCredential("demo", "demo");
// Store the request in the object that we pass into the
// asynchronous operations.
state.Request = request;
state.FileName = fileName;
// Get the event to wait on.
ManualResetEvent waitObject = state.OperationComplete;
// Asynchronously get the stream for the file contents.
request.BeginGetRequestStream(EndGetStreamCallback, state);
// Block the current thread until all operations are complete.
waitObject.WaitOne();
// The operations either completed or threw an exception.
if (state.OperationException != null)
{
throw state.OperationException;
}
Console.WriteLine("The operation completed - {0}", state.StatusDescription);
}
private static void EndGetStreamCallback(IAsyncResult ar)
{
var state = (FtpState) ar.AsyncState;
// End the asynchronous call to get the request stream.
try
{
Stream requestStream = state.Request.EndGetRequestStream(ar);
// Copy the file contents to the request stream.
const int bufferLength = 2048;
var buffer = new byte[bufferLength];
int count = 0;
int readBytes;
FileStream stream = File.OpenRead(state.FileName);
do
{
readBytes = stream.Read(buffer, 0, bufferLength);
requestStream.Write(buffer, 0, readBytes);
count += readBytes;
} while (readBytes != 0);
Console.WriteLine("Writing {0} bytes to the stream.", count);
// IMPORTANT: Close the request stream before sending the request.
requestStream.Close();
// Asynchronously get the response to the upload request.
state.Request.BeginGetResponse(EndGetResponseCallback, state);
}
// Return exceptions to the main application thread.
catch (Exception e)
{
Console.WriteLine("Could not get the request stream.");
state.OperationException = e;
state.OperationComplete.Set();
}
}
// The EndGetResponseCallback method
// completes a call to BeginGetResponse.
private static void EndGetResponseCallback(IAsyncResult ar)
{
var state = (FtpState) ar.AsyncState;
try
{
var response = (FtpWebResponse) state.Request.EndGetResponse(ar);
response.Close();
state.StatusDescription = response.StatusDescription;
// Signal the main application thread that
// the operation is complete.
state.OperationComplete.Set();
}
// Return exceptions to the main application thread.
catch (Exception e)
{
Console.WriteLine("Error getting response.");
state.OperationException = e;
state.OperationComplete.Set();
}
}
}
}
(000005)12/26/2014 15:17:15 PM - (not logged in) (::1)> Connected on port 21, sending welcome message...
(000005)12/26/2014 15:17:15 PM - (not logged in) (::1)> USER demo
(000005)12/26/2014 15:17:15 PM - (not logged in) (::1)> 331 Password required for demo
(000005)12/26/2014 15:17:15 PM - (not logged in) (::1)> PASS ****
(000005)12/26/2014 15:17:15 PM - demo (::1)> 230 Logged on
(000005)12/26/2014 15:17:15 PM - demo (::1)> OPTS utf8 on
(000005)12/26/2014 15:17:15 PM - demo (::1)> 202 UTF8 mode is always enabled. No need to send this command.
(000005)12/26/2014 15:17:15 PM - demo (::1)> PWD
(000005)12/26/2014 15:17:15 PM - demo (::1)> 257 "/" is current directory.
(000005)12/26/2014 15:17:15 PM - demo (::1)> TYPE I
(000005)12/26/2014 15:17:15 PM - demo (::1)> 200 Type set to I
(000005)12/26/2014 15:17:15 PM - demo (::1)> EPSV
(000005)12/26/2014 15:17:15 PM - demo (::1)> 229 Entering Extended Passive Mode (|||7800|)
(000005)12/26/2014 15:17:15 PM - demo (::1)> STOR 100ץצקרתﬤﬢ.txt
(000005)12/26/2014 15:17:15 PM - demo (::1)> 150 Opening data channel for file upload to server of "/100ץצקרתﬤﬢ.txt"
(000005)12/26/2014 15:17:15 PM - demo (::1)> 226 Successfully transferred "/100ץצקרתﬤﬢ.txt"
(000005)12/26/2014 15:17:15 PM - demo (::1)> disconnected.