FtpWebRequest - 传输包含片段标记 (#) 的文件名
FtpWebRequest - Transferring file name containing fragment marker (#)
编辑:不确定它的答案,但它是一种解决方法......而不是查看我添加的文件传输对象。替换为 FTP 字符串并得到我正在寻找的结果,目标文件名现在与源文件名匹配。
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + fileInfo.Name.Replace("#", "%23"));
我有一个已使用多年的现有 C# FTP 进程。实施了一个新的文件命名约定,在实际文件名中使用# 字符。据我所知,# 在文件传输期间被解释为片段标记,导致目标服务器上的文件名不正确。
源文件名:'9300T_#Test.xml'
目标文件名:'9300T_'
有没有办法强制使用实际文件名?
当我在执行过程中查看对象值时,我可以看到原始字符串是正确的,但我还在片段 属性 下看到了“#Test.xml”。
我尝试了 WebRequest、FtpWebRequest 和 Uri 的不同属性。到目前为止,我还没有找到有效的组合,也没有在网上找到解决方案。
我已经使用其他 FTP 客户端(DOS 提示符、Mozilla)进行了测试,文件传输正确,这让我相信解决方案是由 属性 驱动的,或者,这是一个限制我正在使用的对象。
下面是我从产生问题的 windows 表单测试的代码。
谢谢。
string sourcePath = @"C:\FILES\";
string sourcePattern = "9300T*.xml";
string targetServer = "test_server_name";
string targetPath = "/";
string targetLogin = "server_login";
string targetPassword = "login_password";
string[] uploadFiles = Directory.GetFiles(sourcePath, sourcePattern);
// Loop through and process the list.
foreach (string file in uploadFiles)
{
// Create the file information object.
FileInfo fileInfo = new FileInfo(file);
// Create the FTP request object.
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + fileInfo.Name);
ftpRequest.Credentials = new NetworkCredential(targetLogin, targetPassword);
ftpRequest.KeepAlive = false;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.ContentLength = fileInfo.Length;
// Opens a file stream to read the file being uploaded.
FileStream readStream = fileInfo.OpenRead();
// Create the stream to which the upload file is written to.
Stream writeStream = ftpRequest.GetRequestStream(); // -- TARGET FILE IS CREATED WITH WRONG NAME AT THIS POINT
// Set the buffer size.
int bufferLength = 2048;
byte[] buffer = new byte[bufferLength];
// Read from and write to streams until content ends.
int contentLength = readStream.Read(buffer, 0, bufferLength);
while (contentLength != 0)
{
writeStream.Write(buffer, 0, contentLength);
contentLength = readStream.Read(buffer, 0, bufferLength);
}
// Flush and close the streams.
readStream.Flush();
readStream.Close();
writeStream.Flush();
writeStream.Close();
fileInfo.Delete();
}
当您连接文件名以创建 URL 用于 Web 请求时,
您必须使用 percent-enconding, otherwise characters after "#" are considered to be URL fragment 而不是文件名的一部分来转义文件名。
我建议使用像 Uri.EscapeDataString()
这样的函数而不是 Replace("#", "%23")
,因为它可以正确处理所有其他保留字符(例如“@”)。
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + Uri.EscapeDataString(fileInfo.Name));
如果 targetPath 可能包含保留字符,您可能也需要对其进行转义。
编辑:不确定它的答案,但它是一种解决方法......而不是查看我添加的文件传输对象。替换为 FTP 字符串并得到我正在寻找的结果,目标文件名现在与源文件名匹配。
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + fileInfo.Name.Replace("#", "%23"));
我有一个已使用多年的现有 C# FTP 进程。实施了一个新的文件命名约定,在实际文件名中使用# 字符。据我所知,# 在文件传输期间被解释为片段标记,导致目标服务器上的文件名不正确。
源文件名:'9300T_#Test.xml' 目标文件名:'9300T_'
有没有办法强制使用实际文件名?
当我在执行过程中查看对象值时,我可以看到原始字符串是正确的,但我还在片段 属性 下看到了“#Test.xml”。
我尝试了 WebRequest、FtpWebRequest 和 Uri 的不同属性。到目前为止,我还没有找到有效的组合,也没有在网上找到解决方案。
我已经使用其他 FTP 客户端(DOS 提示符、Mozilla)进行了测试,文件传输正确,这让我相信解决方案是由 属性 驱动的,或者,这是一个限制我正在使用的对象。
下面是我从产生问题的 windows 表单测试的代码。
谢谢。
string sourcePath = @"C:\FILES\";
string sourcePattern = "9300T*.xml";
string targetServer = "test_server_name";
string targetPath = "/";
string targetLogin = "server_login";
string targetPassword = "login_password";
string[] uploadFiles = Directory.GetFiles(sourcePath, sourcePattern);
// Loop through and process the list.
foreach (string file in uploadFiles)
{
// Create the file information object.
FileInfo fileInfo = new FileInfo(file);
// Create the FTP request object.
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + fileInfo.Name);
ftpRequest.Credentials = new NetworkCredential(targetLogin, targetPassword);
ftpRequest.KeepAlive = false;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.ContentLength = fileInfo.Length;
// Opens a file stream to read the file being uploaded.
FileStream readStream = fileInfo.OpenRead();
// Create the stream to which the upload file is written to.
Stream writeStream = ftpRequest.GetRequestStream(); // -- TARGET FILE IS CREATED WITH WRONG NAME AT THIS POINT
// Set the buffer size.
int bufferLength = 2048;
byte[] buffer = new byte[bufferLength];
// Read from and write to streams until content ends.
int contentLength = readStream.Read(buffer, 0, bufferLength);
while (contentLength != 0)
{
writeStream.Write(buffer, 0, contentLength);
contentLength = readStream.Read(buffer, 0, bufferLength);
}
// Flush and close the streams.
readStream.Flush();
readStream.Close();
writeStream.Flush();
writeStream.Close();
fileInfo.Delete();
}
当您连接文件名以创建 URL 用于 Web 请求时, 您必须使用 percent-enconding, otherwise characters after "#" are considered to be URL fragment 而不是文件名的一部分来转义文件名。
我建议使用像 Uri.EscapeDataString()
这样的函数而不是 Replace("#", "%23")
,因为它可以正确处理所有其他保留字符(例如“@”)。
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + targetServer + targetPath + Uri.EscapeDataString(fileInfo.Name));
如果 targetPath 可能包含保留字符,您可能也需要对其进行转义。