我想从"filename"属性中提取所有可能类型的有效文件名的Content-Disposition HTTP标头,如以下示例所示:
Content-Disposition: attachment; filename="filename.jpg"
Content-Disposition: attachment; filename=file-2020-April.txt.vbs"
此外,有时文件名包含非ASCII字符,在这种情况下,正确的文件名来自"filename=*"属性,如以下示例:(这只是一个示例,而不是实际数据(
Content-Disposition: attachment; filename="??.txt"; filename*=UTF-8''日本.txt
我使用以下字符串函数仅从filename="中提取
string ContentDispositionHeader;
int startPos = ContentDispositionHeader.find(""");
startPos++;
int endPos = ContentDispositionHeader.find_last_of(""");
int length = endPos - startPos;
string filename = ContentDispositionHeader.substr(startPos, length);
但是,我需要编写代码来管理文件命名情况(普通和UTF-8(。有没有一种更快的方法可以轻松提取文件名。
我相信您无法比O(n)
更快地获得,而n = length of the header
正是您想要的。而且,这是你已经在尝试做的。
下面是一个例子,考虑到引号总是存在,以类似的方式从标题中提取文件名(有关这方面的更多信息,请参阅RFC 6266(;并且,如果存在ASCII格式,则UTF-8格式始终跟在ASCII格式之后。此外,在解析标头时可能需要处理更多的情况。
以下是示例(实时(:
#include <iostream>
#include <string>
#include <vector>
#include <utility>
// Filenames: <ASCII, UTF-8>
using Filenames = std::pair<std::string, std::string>;
Filenames getFilename( const std::string& header )
{
std::string ascii;
const std::string q1 { R"(filename=")" };
if ( const auto pos = header.find(q1); pos != std::string::npos )
{
const auto len = pos + q1.size();
const std::string q2 { R"(")" };
if ( const auto pos = header.find(q2, len); pos != std::string::npos )
{
ascii = header.substr(len, pos - len);
}
}
std::string utf8;
const std::string u { R"(UTF-8'')" };
if ( const auto pos = header.find(u); pos != std::string::npos )
{
utf8 = header.substr(pos + u.size());
}
return { ascii, utf8 };
}
int main()
{
const std::vector<std::string> headers
{
R"(Content-Disposition: attachment; filename="??.txt"; filename*=UTF-8''日本.txt)",
R"(Content-Disposition: attachment; filename*=UTF-8''日本.txt)",
R"(Content-Disposition: attachment; filename="filename.jpg")",
R"(Content-Disposition: attachment; filename="file-2020-April.txt.vbs")"
};
for ( const auto& header : headers )
{
const auto& [ascii, utf8] = getFilename( header );
std::cout << header
<< "ntASCII: " << ascii
<< "ntUTF-8: " << utf8 << 'n';
}
return 0;
}
输出:
Content-Disposition: attachment; filename="??.txt"; filename*=UTF-8''日本.txt
ASCII: ??.txt
UTF-8: 日本.txt
Content-Disposition: attachment; filename*=UTF-8''日本.txt
ASCII:
UTF-8: 日本.txt
Content-Disposition: attachment; filename="filename.jpg"
ASCII: filename.jpg
UTF-8:
Content-Disposition: attachment; filename="file-2020-April.txt.vbs"
ASCII: file-2020-April.txt.vbs
UTF-8: