আমার প্রোগ্রামটি ইন্টারনেট থেকে নির্বিচারে স্ট্রিং নেবে এবং সেগুলিকে ফাইলের নামের জন্য ব্যবহার করবে। এই স্ট্রিংগুলি থেকে খারাপ চরিত্রগুলি অপসারণ করার কোনও সহজ উপায় আছে বা এর জন্য আমার কোনও কাস্টম ফাংশন লিখতে হবে?
আমার প্রোগ্রামটি ইন্টারনেট থেকে নির্বিচারে স্ট্রিং নেবে এবং সেগুলিকে ফাইলের নামের জন্য ব্যবহার করবে। এই স্ট্রিংগুলি থেকে খারাপ চরিত্রগুলি অপসারণ করার কোনও সহজ উপায় আছে বা এর জন্য আমার কোনও কাস্টম ফাংশন লিখতে হবে?
উত্তর:
ওহ, আমি যখন ঘৃণা করি তখন লোকেরা কোন অক্ষরগুলি বৈধ কিনা তা অনুমান করার চেষ্টা করে। সম্পূর্ণরূপে অ-বহনযোগ্য (সর্বদা মনো সম্পর্কে চিন্তাভাবনা করা) হওয়া ছাড়াও, পূর্ববর্তী উভয় মন্তব্যেই আরও 25 টি অবৈধ অক্ষর মিস হয়েছে।
'Clean just a filename
Dim filename As String = "salmnas dlajhdla kjha;dmas'lkasn"
For Each c In IO.Path.GetInvalidFileNameChars
filename = filename.Replace(c, "")
Next
'See also IO.Path.GetInvalidPathChars
অবৈধ অক্ষর ফেলা:
static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars
var validFilename = new string(filename.Where(ch => !invalidFileNameChars.Contains(ch)).ToArray());
অবৈধ অক্ষরগুলি প্রতিস্থাপন করতে:
static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars and an _ for invalid ones
var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? '_' : ch).ToArray());
অবৈধ অক্ষরগুলি প্রতিস্থাপন করতে (এবং হেল * বনাম নরকের মতো সম্ভাব্য নামের সংঘাত এড়াতে):
static readonly IList<char> invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars and replaces invalid chars with a unique letter (Moves the Char into the letter range of unicode, starting at "A")
var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? Convert.ToChar(invalidFileNameChars.IndexOf(ch) + 65) : ch).ToArray());
এই প্রশ্নের হয়েছে জিজ্ঞাসা অনেক বার সামনে এবং, যতবার নির্দিষ্ট আগে, IO.Path.GetInvalidFileNameChars
পর্যাপ্ত নয়।
প্রথমত, পিআরএন এবং সিওএন এর মতো অনেক নাম রয়েছে যা সংরক্ষিত রয়েছে এবং ফাইলের জন্য অনুমোদিত নয়। কেবলমাত্র মূল ফোল্ডারে অন্য নাম অনুমোদিত নয়। একটি সময়ের মধ্যে শেষ হওয়া নামগুলিও অনুমোদিত নয়।
দ্বিতীয়ত, দৈর্ঘ্যের বিভিন্ন সীমাবদ্ধতা রয়েছে। এনটিএফএসের জন্য সম্পূর্ণ তালিকাটি এখানে পড়ুন ।
তৃতীয়ত, আপনি অন্যান্য সীমাবদ্ধতা রয়েছে এমন ফাইল সিস্টেমে সংযুক্ত করতে পারেন। উদাহরণস্বরূপ, আইএসও 9660 ফাইলের নামগুলি "-" দিয়ে শুরু করতে পারে না তবে এটি ধারণ করতে পারে।
চতুর্থত, দুটি প্রক্রিয়া যদি "নির্বিচারে" একই নামটি গ্রহণ করে তবে আপনি কী করবেন?
সাধারণভাবে, ফাইলের নামের জন্য বাহ্যিকভাবে উত্পাদিত নাম ব্যবহার করা একটি খারাপ ধারণা। আমি আপনার নিজের ব্যক্তিগত ফাইলের নাম উত্পন্ন করার এবং মানব-পঠনযোগ্য নামগুলি অভ্যন্তরীণভাবে সংরক্ষণ করার পরামর্শ দিচ্ছি।
আমি গ্রাওনওল্ফের সাথে একমত এবং এর সুপারিশ করব Path.GetInvalidFileNameChars()
এখানে আমার সি # অবদান:
string file = @"38?/.\}[+=n a882 a.a*/|n^%$ ad#(-))";
Array.ForEach(Path.GetInvalidFileNameChars(),
c => file = file.Replace(c.ToString(), String.Empty));
পিএস - এটি হওয়া উচিত এর চেয়ে আরও গুপ্ত - আমি সংক্ষিপ্ত হওয়ার চেষ্টা করছিলাম।
Array.ForEach
কেবল foreach
এখানে পরিবর্তে ব্যবহার করবেন
Path.GetInvalidFileNameChars().Aggregate(file, (current, c) => current.Replace(c, '-'))
এখানে আমার সংস্করণ:
static string GetSafeFileName(string name, char replace = '_') {
char[] invalids = Path.GetInvalidFileNameChars();
return new string(name.Select(c => invalids.Contains(c) ? replace : c).ToArray());
}
আমি নিশ্চিত না যে কীভাবে getInuthorFileNameChars এর ফলাফল গণনা করা হয়, তবে "গেট" পরামর্শ দেয় এটি অ-তুচ্ছ, সুতরাং আমি ফলাফলগুলি ক্যাশে করি। আরও, এটি কেবল একবারে একাধিক বারের পরিবর্তে ইনপুট স্ট্রিংকে অনুসরণ করে, যেমন উপরে থাকা সমাধানগুলি যেমন অবৈধ অক্ষরের সেটটি পুনরাবৃত্তি করে, একবারে উত্সের স্ট্রিং-এ প্রতিস্থাপন করে। এছাড়াও, আমি যেখানে-ভিত্তিক সমাধানগুলি পছন্দ করি তবে আমি সেগুলি অপসারণের পরিবর্তে অবৈধ অক্ষরগুলি প্রতিস্থাপন করতে পছন্দ করি। পরিশেষে, আমার প্রতিস্থাপন হ'ল স্ট্রিংটিতে পুনরাবৃত্তি হওয়ার সাথে সাথে অক্ষরে স্ট্রিংগুলিতে রূপান্তর এড়ানোর জন্য একটি অক্ষর।
আমি বলি যে ডাব্লু / ও প্রোফাইলিং করছে - এটি আমার কাছে কেবল "অনুভূত" হয়েছে। :)
new HashSet<char>(Path.GetInvalidFileNameChars())
ও (এন) গণনা এড়াতে করতে পারেন - মাইক্রো-অপ্টিমাইজেশন।
আমি এখন যে ফাংশনটি ব্যবহার করছি তা এখানে রয়েছে (সি # উদাহরণের জন্য ধন্যবাদ জ্যাকলাম):
public static string MakeSafeFilename(string filename, char replaceChar)
{
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
filename = filename.Replace(c, replaceChar);
}
return filename;
}
সুবিধার জন্য আমি এটি "সহায়ক" শ্রেণিতে রেখেছি।
আপনি যদি সমস্ত বিশেষ অক্ষরগুলি দ্রুত বের করতে চান যা কখনও কখনও ফাইলের নামের জন্য আরও বেশি ব্যবহারকারী পাঠযোগ্য হয় এটি দুর্দান্তভাবে কাজ করে:
string myCrazyName = "q`w^e!r@t#y$u%i^o&p*a(s)d_f-g+h=j{k}l|z:x\"c<v>b?n[m]q\\w;e'r,t.y/u";
string safeName = Regex.Replace(
myCrazyName,
"\W", /*Matches any nonword character. Equivalent to '[^A-Za-z0-9_]'*/
"",
RegexOptions.IgnoreCase);
// safeName == "qwertyuiopasd_fghjklzxcvbnmqwertyu"
\W
অ-আলফা-সংখ্যার ( [^A-Za-z0-9_]
) এর চেয়ে বেশি মেলে । সমস্ত ইউনিকোড 'শব্দের' অক্ষর (русский 中文 ... ইত্যাদি) আর প্রতিস্থাপন করা হবে না। তবে এটি একটি ভাল জিনিস।
.
আপনাকে সরিয়ে দেয় যাতে আপনাকে প্রথমে এক্সটেনশানটি বের করতে হবে এবং পরে এটি আবার যুক্ত করতে হবে।
static class Utils
{
public static string MakeFileSystemSafe(this string s)
{
return new string(s.Where(IsFileSystemSafe).ToArray());
}
public static bool IsFileSystemSafe(char c)
{
return !Path.GetInvalidFileNameChars().Contains(c);
}
}
স্ট্রিংটিকে বেস বেসের সমতুল্যে কেন রূপান্তর করবেন না:
string UnsafeFileName = "salmnas dlajhdla kjha;dmas'lkasn";
string SafeFileName = Convert.ToBase64String(Encoding.UTF8.GetBytes(UnsafeFileName));
আপনি যদি এটিকে আবার রূপান্তর করতে চান তবে আপনি এটি পড়তে পারেন:
UnsafeFileName = Encoding.UTF8.GetString(Convert.FromBase64String(SafeFileName));
আমি এলোমেলো বর্ণনা থেকে অনন্য নামের পিএনজি ফাইলগুলি সংরক্ষণ করতে এটি ব্যবহার করেছি।
ক্লোরপ্লেয়ারের ( http://github.com/Zoomicon/ClipFlair ) স্ট্রিংএক্সটেনশনগুলি স্ট্যাটিক ক্লাস (ইউটিলেস.সিলভারলাইট প্রজেক্ট) উপরের ডোর হাই আর্ক দ্বারা পোস্ট করা সম্পর্কিত স্ট্যাকওভারফ্লো প্রশ্নগুলির লিঙ্কগুলি থেকে প্রাপ্ত তথ্যের উপর ভিত্তি করে আমি এখানে যা যুক্ত করেছি তা এখানে :
public static string ReplaceInvalidFileNameChars(this string s, string replacement = "")
{
return Regex.Replace(s,
"[" + Regex.Escape(new String(System.IO.Path.GetInvalidPathChars())) + "]",
replacement, //can even use a replacement string of any length
RegexOptions.IgnoreCase);
//not using System.IO.Path.InvalidPathChars (deprecated insecure API)
}
private void textBoxFileName_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = CheckFileNameSafeCharacters(e);
}
/// <summary>
/// This is a good function for making sure that a user who is naming a file uses proper characters
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
internal static bool CheckFileNameSafeCharacters(System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar.Equals(24) ||
e.KeyChar.Equals(3) ||
e.KeyChar.Equals(22) ||
e.KeyChar.Equals(26) ||
e.KeyChar.Equals(25))//Control-X, C, V, Z and Y
return false;
if (e.KeyChar.Equals('\b'))//backspace
return false;
char[] charArray = Path.GetInvalidFileNameChars();
if (charArray.Contains(e.KeyChar))
return true;//Stop the character from being entered into the control since it is non-numerical
else
return false;
}
আমি এটি দ্রুত এবং সহজে বুঝতে সহজ হিসাবে ব্যবহার করে দেখতে পেলাম:
<Extension()>
Public Function MakeSafeFileName(FileName As String) As String
Return FileName.Where(Function(x) Not IO.Path.GetInvalidFileNameChars.Contains(x)).ToArray
End Function
এই কাজ করে কারণ string
হল IEnumerable
হিসেবে char
অ্যারে এবং সেখানে একটি হল string
কন্সট্রাকটর স্ট্রিংটি একটি লাগে char
অ্যারের।
আমার পুরানো প্রকল্পগুলি থেকে, আমি এই সমাধানটি পেয়েছি, যা 2 বছর ধরে নিখুঁতভাবে কাজ করছে। আমি অবৈধ অক্ষরগুলিকে "!" দিয়ে প্রতিস্থাপন করছি, এবং তারপরে দ্বিগুণ !! আপনার নিজের চর ব্যবহার করুন use
public string GetSafeFilename(string filename)
{
string res = string.Join("!", filename.Split(Path.GetInvalidFileNameChars()));
while (res.IndexOf("!!") >= 0)
res = res.Replace("!!", "!");
return res;
}
অনেক অ্যানভার ব্যবহার করার পরামর্শ দেয় Path.GetInvalidFileNameChars()
যা আমার কাছে খারাপ সমাধান বলে মনে হয়। আমি আপনাকে ব্ল্যাকলিস্টিংয়ের পরিবর্তে হোয়াইটলিস্টিং ব্যবহার করতে উত্সাহিত করি কারণ হ্যাকাররা সর্বদা এটিকে বাইপাস করার জন্য সর্বদা উপায় খুঁজে পাবে।
আপনি যে কোডটি ব্যবহার করতে পারেন তার উদাহরণ এখানে রয়েছে:
string whitelist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";
foreach (char c in filename)
{
if (!whitelist.Contains(c))
{
filename = filename.Replace(c, '-');
}
}