java - التحقق من صحة اسم ملف على ويندوز




regex windows (8)

تبدو جيدا. على الأقل إذا كنا نؤمن بهذا المورد: http://msdn.microsoft.com/en-us/library/aa365247٪28v=vs.85٪29.aspx

لكنني سأبسط استخدام الشفرة. يكفي البحث عن أحد هذه الأحرف ليقول أن الاسم غير صالح ، لذلك:

public static boolean isValidName(String text)
{
    Pattern pattern = Pattern.compile("[^/./\\:*?\"<>|]");
    return !pattern.matcher(text).find();
}

هذا التعبير العادي أبسط وسيعمل بشكل أسرع.

public static boolean isValidName(String text)
{
    Pattern pattern = Pattern.compile("^[^/./\\:*?\"<>|]+$");
    Matcher matcher = pattern.matcher(text);
    boolean isMatch = matcher.matches();
    return isMatch;
}

هل تضمن هذه الطريقة اسمًا صحيحًا على نظام التشغيل Windows؟


حسنًا ، أعتقد أن الطريقة التالية ستضمن اسم ملف صالحًا:

public static boolean isValidName(String text)
{
    try
    {
        File file = new File(text);
        file.createNewFile();
        if(file.exists()) file.delete();
        return true;
    }
    catch(Exception ex){}
    return false;
}

ماذا تعتقد؟


لا يكفي ، في Windows و DOS ، قد تكون بعض الكلمات محفوظة أيضًا ولا يمكن استخدامها كأسماء ملفات.

CON, PRN, AUX, CLOCK$, NUL
COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.

رؤية ~

http://en.wikipedia.org/wiki/Filename

تصحيح:

يقوم Windows عادةً بتحديد أسماء الملفات إلى 260 حرفًا. ولكن يجب أن يكون اسم الملف أقصر من ذلك ، حيث يتم تضمين المسار الكامل (مثل C: \ Program Files \ filename.txt) في عدد الأحرف هذا.

ولهذا السبب قد تواجه أحيانًا خطأ عند نسخ ملف يحمل اسم ملف طويل جدًا إلى موقع له مسار أطول من موقعه الحالي.


لن يتحقق هذا الحل إلا إذا كان اسم ملف معين صالحًا وفقًا لقواعد نظام التشغيل بدون إنشاء ملف.

لا تزال بحاجة إلى معالجة حالات فشل أخرى عند إنشاء الملف بالفعل (على سبيل المثال ، أذون غير كافية ، وعدم وجود مساحة على القرص ، والقيود الأمنية).

import java.io.File;
import java.io.IOException;

public class FileUtils {
  public static boolean isFilenameValid(String file) {
    File f = new File(file);
    try {
       f.getCanonicalPath();
       return true;
    }
    catch (IOException e) {
       return false;
    }
  }

  public static void main(String args[]) throws Exception {
    // true
    System.out.println(FileUtils.isFilenameValid("well.txt"));
    System.out.println(FileUtils.isFilenameValid("well well.txt"));
    System.out.println(FileUtils.isFilenameValid(""));

    //false
    System.out.println(FileUtils.isFilenameValid("test.T*T"));
    System.out.println(FileUtils.isFilenameValid("test|.TXT"));
    System.out.println(FileUtils.isFilenameValid("te?st.TXT"));
    System.out.println(FileUtils.isFilenameValid("con.TXT")); // windows
    System.out.println(FileUtils.isFilenameValid("prn.TXT")); // windows
    }
  }

من المستحيل تنفيذ طريقة تضمن ، بشكل عام ، أن اسم ملف Windows صالحًا - أنه قانوني لإنشاء ملف بهذا الاسم - سيكون من المستحيل تنفيذه.

من السهل نسبياً ضمان أن اسم ملف Windows غير صالح . بعض من regexes أخرى تحاول القيام بذلك. ومع ذلك ، فإن السؤال الأصلي يطلب تأكيدًا أقوى: طريقة تضمن أن اسم الملف صحيح على Windows.

يشير مرجع MSDN المذكورة في إجابات أخرى إلى أن اسم ملف Windows لا يمكن أن يحتوي على "أي حرف آخر لا يسمح به نظام الملفات الهدف". على سبيل المثال ، قد يكون الملف الذي يحتوي على NUL غير صالح في بعض أنظمة الملفات ، كما سيتم تمديد أحرف Unicode في بعض أنظمة الملفات القديمة. وبالتالي ، سيكون ملفًا باسم ☃.txt صالحًا في بعض الحالات ، ولكن ليس ملفات أخرى. لذا سواء كان افتراضية isValidName(\"☃\") سيعود صحيح يعتمد على نظام الملفات الأساسي.

ومع ذلك ، لنفترض أن هذه الوظيفة متحفظة وتتطلب أن يتكون اسم الملف من حروف ASCII قابلة للطباعة. تعتمد كافة إصدارات Windows الحديثة أصلاً تنسيقات ملفات NTFS و FAT32 و FAT16 ، والتي تقبل أسماء ملفات Unicode. ولكن يمكن تثبيت برامج تشغيل أنظمة الملفات العشوائية ، وإمكانية إنشاء نظام ملفات لا يسمح ، على سبيل المثال ، بالحرف "n". وبالتالي ، لا يمكن أن يكون "ملفًا" صحيحًا حتى لملف بسيط مثل "snowman.txt".

لكن حتى مع الحالات المتطرفة جانبا ، هناك تعقيدات أخرى. على سبيل المثال ، لا يمكن وجود ملف يسمى "$ LogFile" في جذر وحدة تخزين NTFS ، ولكن يمكن أن توجد في مكان آخر على وحدة التخزين. وبالتالي ، بدون معرفة الدليل ، لا يمكننا معرفة ما إذا كان "$ LogFile" هو اسم صالح. ولكن قد يكون "C: \ data \ $ LogFile" غير صالح إذا ، على سبيل المثال ، "c: \ data \" هو ارتباط رمزي إلى جذر وحدة تخزين NTFS أخرى. (وبالمثل ، يمكن أن تكون "D: \ $ LogFile" صالحة إذا كان D: هو اسم مستعار إلى دليل فرعي من وحدة تخزين NTFS.)

هناك المزيد من التعقيدات. تدفقات البيانات البديلة على الملفات ، على سبيل المثال ، قانونية على وحدات تخزين NTFS ، لذا قد يكون "snowman.txt: ☃" صالحًا. تحتوي جميع أنظمة الملفات الرئيسية الثلاثة في Windows على إعادة تنظيم طول المسار ، وبالتالي فإن صلاحية اسم الملف تعمل أيضًا على المسار. ولكن قد لا يكون طول المسار الفعلي متاحًا لـ isValidName إذا كان المسار عبارة عن اسم مستعار افتراضي ، أو محرك أقراص شبكة معيّن ، أو ارتباط رمزي بدلاً من مسار فعلي على وحدة التخزين.

اقترح البعض الآخر بديلاً: إنشاء ملف بالاسم المقترح ثم حذفه ، وإرجاع true إذا وفقط إذا نجح الإنشاء. هذا النهج لديه العديد من المشاكل العملية والنظرية. واحد ، كما هو مبين في وقت سابق ، هو أن الصلاحية هي وظيفة لكل من اسم الملف والمسار ، لذلك قد تختلف صلاحية c: \ test \ ☃.txt عن صحة c: \ test2 \ ☃.txt. أيضاً ، قد تفشل الدالة في كتابة الملف لأي عدد من الأسباب التي لا تتعلق بصلاحية الملف ، مثل عدم وجود إذن الكتابة إلى الدليل. العيب الثالث هو أن صلاحية اسم الملف غير مطلوبة لتكون غير حتمية: فقد لا يسمح نظام ملف افتراضي ، على سبيل المثال ، باستبدال الملف المحذوف ، أو (من الناحية النظرية) يمكنه حتى أن يقرر بشكل عشوائي إذا كان اسم الملف صحيحًا.

isInvalidFileName(String text) بديل بسيط إلى حد ما لإنشاء أسلوب isInvalidFileName(String text) تقوم بإرجاع true إذا كان الملف مضمونًا غير صالح في Windows؛ أسماء الملفات مثل "aux" و "*" و "abc.txt". سيعود صحيح. أولاً ، يتحقق من عملية إنشاء الملف التأكد من أن اسم الملف غير صالح ، وسيتوقف ، في حالة قيامه بإرجاع false. وإلا ، فقد تحاول الطريقة إنشاء الملف ، أثناء الاستعداد لحالة الحافة حيث يتعذر إنشاء الملف لأن اسم الملف غير صالح.


نشر إجابة جديدة لأني لا أمتلك الحد الأدنى للتعليق على رمز Eng.Fouad

public static boolean isValidName(String text)
{
    try
    {
        File file = new File(text);
        if(file.createNewFile()) file.delete();
        return true;
    }
    catch(Exception ex){}
    return false;
}

تغيير بسيط في إجابتك يمنع حذف ملف موجود مسبقًا. يتم حذف الملفات فقط إذا تم إنشاؤها أثناء استدعاء الأسلوب هذا ، بينما تكون قيمة الإرجاع هي نفسها.


يمكنك التحقق من جميع الأسماء المحجوزة (AUX و CON وما شابه) ثم استخدام هذا الرمز:

bool invalidName = GetFileAttributes(name) == INVALID_FILE_ATTRIBUTES && 
        GetLastError() == ERROR_INVALID_NAME;

للتحقق من أي قيود إضافية. ولكن تجدر الإشارة إلى أنه في حالة التحقق من وجود اسم في دليل غير موجود ، فستحصل على ERROR_PATH_NOT_FOUND ما إذا كان الاسم صحيحًا أم لا.

على أي حال ، يجب أن تتذكر المثل القديم:

من الأسهل طلب المغفرة من الحصول على إذن.


Here يمكنك العثور على أسماء الملفات المسموح بها.

الحروف التالية غير مسموح بها:

  • <(أقل من)
  • (أكثر من)

  • : (القولون)
  • " (اقتباس مزدوج)
  • / (مائل)
  • \ (مائل عمودي)
  • | (شريط عمودي أو أنبوب)
  • ؟ (علامة استفهام)
  • * (علامة النجمة)

  • القيمة الصحيحة صفر ، يشار إليها أحيانًا بحرف ASCII NUL.

  • الأحرف التي تكون تمثيلها الصحيح في النطاق من 1 إلى 31 ، باستثناء تدفقات البيانات البديلة حيث يتم السماح بهذه الأحرف. لمزيد من المعلومات حول تدفقات الملف ، راجع File Streams.
  • أي حرف آخر لا يسمح به نظام الملفات الهدف.






filenames