Chương trình của tôi sẽ lấy các chuỗi tùy ý từ internet và sử dụng chúng cho tên tệp. Có một cách đơn giản để loại bỏ các ký tự xấu từ các chuỗi này hay tôi cần phải viết một hàm tùy chỉnh cho điều này?Có cách nào để tạo chuỗi đường dẫn an toàn trong C#?
Trả lời
Ugh, tôi ghét nó khi mọi người cố gắng đoán xem ký tự nào hợp lệ. Bên cạnh việc hoàn toàn không di chuyển (luôn nghĩ về Mono), cả hai nhận xét trước đó đều bỏ lỡ hơn 25 ký tự không hợp lệ.
'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
Nó sẽ không tạo ra nhiều khác biệt trong tình huống này. Lỗi Windows chỉ phàn nàn về số lượng ký tự đó. Cảm ơn bạn đã chỉ ra các GetInvalidFileNameChars, mặc dù, tôi sẽ không đi qua mà trước. Tôi sẽ ghi nhớ điều đó. – BenAlabaster
Phiên bản C#: foreach (var c trong Path.GetInvalidFileNameChars()) {fileName = fileName.Replace (c, '-'); } – jcollum
Giải pháp này xử lý xung đột tên như thế nào? Có vẻ như nhiều hơn một chuỗi có thể khớp với một tên tệp duy nhất (ví dụ: "Địa ngục?" Và "Địa ngục *"). Nếu bạn ổn, chỉ xóa các ký tự vi phạm sau đó tốt; nếu không bạn cần phải cẩn thận để xử lý xung đột tên. –
Tôi đồng ý với Grauenwolf và rất muốn giới thiệu các Path.GetInvalidFileNameChars()
Dưới đây là tôi C# đóng góp:
string file = @"38?/.\}[+=n a882 a.a*/|n^%$ ad#(-))";
Array.ForEach(Path.GetInvalidFileNameChars(),
c => file = file.Replace(c.ToString(), String.Empty));
tái bút: - điều này khó hiểu hơn là - tôi đã cố gắng súc tích.
Tại sao trên thế giới bạn sử dụng 'Array.ForEach' thay vì chỉ' foreach' ở đây –
Nếu bạn muốn thậm chí còn ngắn gọn hơn/khó hiểu hơn: 'Path.GetInvalidFileNameChars(). Tổng hợp (tệp, (current, c) => current.Replace (c, '-')) ' –
@ BlueRaja-DannyPflughoeft Vì bạn muốn làm chậm hơn? –
Nếu bạn muốn nhanh chóng loại bỏ tất cả các ký tự đặc biệt đó là người sử dụng đôi khi dễ đọc hơn cho tên tập tin này làm việc độc đáo:
string myCrazyName = "q`w^[email protected]#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"
thực sự '\ W' khớp với nhiều hơn không phải alpha-numerics (' [^ A-Za-z0-9_] '). Tất cả các ký tự 'từ' Unicode (русский 中文 ..., v.v.) cũng sẽ không được thay thế. Nhưng đây là một điều tốt. – Ishmael
Nhược điểm duy nhất là điều này cũng loại bỏ '.' vì vậy bạn phải giải nén phần mở rộng đầu tiên, và thêm nó lại sau. – awe
Đây là chức năng mà tôi đang sử dụng hiện nay (nhờ jcollum cho C# chẳng hạn) :
public static string MakeSafeFilename(string filename, char replaceChar)
{
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
filename = filename.Replace(c, replaceChar);
}
return filename;
}
Tôi chỉ đặt điều này trong lớp "Người trợ giúp" để thuận tiện.
Tước ký tự không hợp lệ:
static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars
var validFilename = new string(filename.Where(ch => !invalidFileNameChars.Contains(ch)).ToArray());
Để thay thế ký tự không hợp lệ:
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());
Để thay thế ký tự không hợp lệ (và tránh tiềm năng tên xung đột như Hell * vs Hell $):
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());
"dải ký tự không hợp lệ" hoạt động như một nét duyên dáng. cảm ơn. – Nani
Câu hỏi này đã được yêu cầu manytimesbefore và, như được chỉ ra nhiều lần trước đây, IO.Path.GetInvalidFileNameChars
không đủ.
Đầu tiên, có nhiều tên như PRN và CON được đặt trước và không được phép cho tên tệp. Có những tên khác không được phép chỉ ở thư mục gốc. Các tên kết thúc trong một khoảng thời gian cũng không được phép.
Thứ hai, có nhiều giới hạn độ dài khác nhau. Đọc danh sách đầy đủ cho NTFS here.
Thứ ba, bạn có thể đính kèm vào hệ thống tệp có các giới hạn khác. Ví dụ: tên tệp ISO 9660 không thể bắt đầu bằng "-" nhưng có thể chứa nó.
Thứ tư, bạn sẽ làm gì nếu hai quá trình "tùy tiện" chọn cùng một tên?
Nói chung, việc sử dụng tên được tạo bên ngoài cho tên tệp là một ý tưởng tồi. Tôi đề nghị tạo tên tệp riêng của bạn và lưu trữ tên người có thể đọc được trong nội bộ.
Mặc dù bạn là chính xác về mặt kỹ thuật, GetInvalidFileNameChars là tốt cho 80% + của các tình huống bạn muốn sử dụng nó trong, do đó nó là một câu trả lời tốt. Câu trả lời của bạn sẽ thích hợp hơn khi nhận xét về câu trả lời được chấp nhận mà tôi nghĩ. – CubanX
Tôi đồng ý với DourHighArch. Lưu tệp nội bộ dưới dạng guid, tham chiếu đến "tên thân thiện" được lưu trữ trong cơ sở dữ liệu. Đừng để người dùng kiểm soát đường dẫn của bạn trên trang web hoặc họ sẽ cố gắng đánh cắp web.config của bạn. Nếu bạn kết hợp viết lại url để làm cho nó sạch sẽ nó sẽ chỉ làm việc cho các url thân thiện phù hợp trong cơ sở dữ liệu. – rtpHarry
tôi thấy sử dụng này là nhanh chóng và dễ hiểu:
<Extension()>
Public Function MakeSafeFileName(FileName As String) As String
Return FileName.Where(Function(x) Not IO.Path.GetInvalidFileNameChars.Contains(x)).ToArray
End Function
này hoạt động vì một string
là IEnumerable
như một mảng char
và có một chuỗi string
constructor mà phải mất một mảng char
.
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);
}
}
Đây là những gì tôi chỉ thêm vào ClipFlair của (http://clipflair.codeplex.com) StringExtensions lớp tĩnh (dự án Utils.Silverlight), dựa trên thông tin thu thập được từ các liên kết đến câu hỏi stackoverflow liên quan đăng bởi Dour cao Arch trên:
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)
}
Dưới đây là phiên bản của tôi:
static string GetSafeFileName(string name, char replace = '_') {
char[] invalids = Path.GetInvalidFileNameChars();
return new string(name.Select(c => invalids.Contains(c) ? replace : c).ToArray());
}
tôi không chắc chắn như thế nào là kết quả của GetInvalidFileNameChars được tính, nhưng "Nhận" cho thấy nó không đố l, vì vậy tôi lưu trữ kết quả. Hơn nữa, điều này chỉ đi qua chuỗi đầu vào một lần thay vì nhiều lần, như các giải pháp ở trên mà lặp qua tập hợp các ký tự không hợp lệ, thay thế chúng trong chuỗi nguồn một tại một thời điểm. Ngoài ra, tôi thích các giải pháp ở đâu đó, nhưng tôi thích thay thế các ký tự không hợp lệ thay vì xóa chúng. Cuối cùng, thay thế của tôi chính xác là một ký tự để tránh chuyển đổi ký tự thành chuỗi khi tôi lặp qua chuỗi.
Tôi nói tất cả những điều đó đang làm hồ sơ - điều này chỉ "cảm thấy" tốt với tôi. :)
Bạn có thể làm 'mới HashSet
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;
}
Tại sao không chuyển đổi chuỗi thành một tương đương Base64 như thế này:
string UnsafeFileName = "salmnas dlajhdla kjha;dmas'lkasn";
string SafeFileName = Convert.ToBase64String(Encoding.UTF8.GetBytes(UnsafeFileName));
Nếu bạn muốn chuyển đổi nó trở lại, do đó bạn có thể đọc nó:
UnsafeFileName = Encoding.UTF8.GetString(Convert.FromBase64String(SafeFileName));
tôi đã sử dụng điều này để lưu tệp PNG với tên duy nhất từ mô tả ngẫu nhiên.
- 1. Làm cách nào để tạo một tên đường dẫn tham gia an toàn bằng ruby?
- 2. Tạo chuỗi dữ liệu an toàn trong C#
- 3. Tạo đường dẫn từ chuỗi trong Java7
- 4. Chủ đề chuỗi C# có an toàn không?
- 5. tạo std :: chuỗi từ char * một cách an toàn
- 6. Tạo chuỗi không an toàn từ char []
- 7. Tạo đường dẫn tệp trong C#
- 8. Tạo chuỗi tên an toàn ngẫu nhiên và chuỗi an toàn URL
- 9. Chuỗi an toàn của Netty Channel.write có an toàn không?
- 10. Có phải chuỗi được tạo ra Axis2 an toàn không?
- 11. Có tốt hơn khi tạo chuỗi băm an toàn không?
- 12. Làm cách nào để tạo chuỗi kích hoạt an toàn trong php?
- 13. Trong Perl, làm cách nào để tạo một FIFO tạm thời một cách an toàn?
- 14. Chuỗi RNGCryptoServiceProvider.GetBytes có an toàn không?
- 15. SecureString có an toàn không?
- 16. Có cách nào an toàn để chuyển đổi Bộ sưu tập thành chuỗi trong F # không?
- 17. Chuỗi NSUserDefault có an toàn không?
- 18. là chuỗi java.util.UUID có an toàn không?
- 19. Mã C sau có an toàn không?
- 20. Làm cách nào để tạo một đường dẫn ngẫu nhiên?
- 21. Mảng an toàn không có khóa an toàn
- 22. Làm cách nào để chuyển đổi đường dẫn Unicode thành chuỗi c?
- 23. Chủ đề có thể được tạo một cách an toàn trong khi khởi tạo tĩnh không?
- 24. Tạo chuỗi 'văn bản thuần' an toàn khỏi nứt?
- 25. Cách tạo một biến tĩnh an toàn
- 26. C socket API có an toàn không?
- 27. Là chuỗi String.intern() an toàn
- 28. Cách tạo chủ đề an toàn EntityManagerFactory?
- 29. Làm cách nào để tạo một HashCode trong .net (C#) cho một chuỗi an toàn để lưu trữ trong cơ sở dữ liệu?
- 30. Có phải chuỗi an toàn của SQLite.Net không?
bản sao có thể có của [Trình dọn dẹp tên tệp an toàn/được phép cho .NET] (http://stackoverflow.com/questions/1862993/safe-allowed-filename-cleaner-for-net) – N8allan