ما هي الأسباب المحتملة لjava.io.IOException:"اسم الملف أو اسم الدليل أو بناء جملة تسمية وحدة التخزين غير صحيح"

StackOverflow https://stackoverflow.com/questions/131901

  •  02-07-2019
  •  | 
  •  

سؤال

أحاول نسخ ملف باستخدام الكود التالي:

File targetFile = new File(targetPath + File.separator + filename);
...
targetFile.createNewFile();
fileInputStream = new FileInputStream(fileToCopy);
fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[64*1024];
int i = 0;
while((i = fileInputStream.read(buffer)) != -1) {
    fileOutputStream.write(buffer, 0, i);
}

بالنسبة لبعض المستخدمين targetFile.createNewFile يؤدي إلى هذا الاستثناء:

java.io.IOException: The filename, directory name, or volume label syntax is incorrect
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:850)

يبدو أن اسم الملف واسم الدليل صحيحان.الدليل targetPath يتم التحقق من وجوده قبل تنفيذ كود النسخ ويبدو اسم الملف كما يلي: AB_timestamp.xml

لدى المستخدم أذونات الكتابة إلى targetPath ويمكن نسخ الملف دون مشاكل باستخدام نظام التشغيل.

وبما أنني لا أستطيع الوصول إلى جهاز ما، يحدث هذا حتى الآن ولا يمكنني إعادة إنتاج المشكلة على جهازي الخاص، لذا أتوجه إليك للحصول على تلميحات حول سبب هذا الاستثناء.

هل كانت مفيدة؟

المحلول

جرب هذا، لأنه يهتم أكثر بضبط أحرف فاصل الدليل في المسار بين targetPath واسم الملف:

File targetFile = new File(targetPath, filename);

نصائح أخرى

لقد واجهت نفس المشكلة.أعتقد أن الأمر له علاقة بإذن الوصول للكتابة.لقد حصلت على الخطأ أثناء محاولتي الكتابة إلى c:\ ولكن عند التغيير إلى D:\ كل شيء سار على ما يرام.من الواضح أن Java لم يكن لديها إذن بالكتابة إلى محرك النظام الخاص بي (تشغيل Windows 7 المثبت على C :)

لمعلوماتك، لقد حصلت على ذلك عندما كانت أسماء الملفات الخاصة بي تحتوي على طابع زمني بنقطتين، على سبيل المثال myfile_HH:mm:ss.csv أدت إزالة النقطتين إلى إصلاح المشكلة.

هنا هو برنامج الاختبار الذي أستخدمه

import java.io.File;
public class TestWrite {

    public static void main(String[] args) {
        if (args.length!=1) {
            throw new IllegalArgumentException("Expected 1 argument: dir for tmp file");
        }
        try  {
            File.createTempFile("bla",".tmp",new File(args[0]));
        } catch (Exception e) {
            System.out.println("exception:"+e);
            e.printStackTrace();
        }
    }
}

حاول إنشاء الملف في دليل مختلف - على سبيل المثال."C:\" بعد التأكد من أن لديك حق الوصول للكتابة إلى هذا الدليل.إذا نجح ذلك، فإن اسم مسار الملف خاطئ.

ألقِ نظرة على التعليق الموجود في الاستثناء وحاول تغيير جميع العناصر الموجودة في اسم مسار الملف.تجربة.استخلاص النتائج.

هل تتحقق من أن targetPath هو دليل، أم أنه يوجد شيء بهذا الاسم فقط؟(أعلم أنك تقول أنه يمكن للمستخدم نسخه من نظام التشغيل، ولكن ربما يكتب شيئًا آخر).

هل ينتهي targetPath بـ File.separator بالفعل؟

(سيكون من المفيد أن تتمكن من تسجيل الدخول وإخبارنا بقيمة targetPath واسم الملف في حالة الفشل)

ربما المشكلة هي أنه يتم نسخ الملف عبر الشبكة، إلى محرك أقراص مشترك؟أعتقد أن Java يمكن أن تواجه مشكلات عند كتابة الملفات باستخدام NFS عندما يكون المسار مثل المجلد \mypc\myshared.

ما هو المسار الذي تحدث فيه هذه المشكلة؟

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

بالإضافة إلى ذلك، يمكنك أيضًا إلقاء نظرة على القنوات بدلاً من استخدام حلقة.؛-)

أنت تقول "لبعض المستخدمين" - فهل يعمل مع الآخرين؟ما هو الفرق هنا، هل يقوم المستخدمون بتشغيل مثيلات مختلفة على أجهزة مختلفة، أم أن هذا خادم يخدم المستخدمين المتزامنين؟

إذا كان الأخير، أود أن أقول أنه خطأ في التزامن بطريقة أو بأخرى - تحقق من خيطين حاول إنشاء الملف باستخدام WinNTFileSystem.createFileExclusively(Native Method) في وقت واحد.

لا تتم مزامنة createNewFile أو createFileExclusively عندما ألقي نظرة على مصدر OpenJDK، لذلك قد تضطر إلى مزامنة هذه الكتلة بنفسك.

ربما الملف موجود بالفعل.قد يكون الأمر كذلك إذا لم تكن دقة الطابع الزمني لديك جيدة بما يكفي.نظرًا لأنه IOException الذي تحصل عليه، فقد لا يكون مشكلة تتعلق بالأذونات (وفي هذه الحالة ستحصل على SecurityException).

سأتحقق أولاً من وجود الملف قبل محاولة إنشاء الملف ومحاولة تسجيل ما يحدث.

ينظر الى إنشاء ملف منطقي عام () لمزيد من المعلومات حول الطريقة التي تستخدمها.

نظرًا لأنني لم أتمكن من إعادة إنتاج الخطأ على جهازي أو وضع اليد على جهاز المستخدم حيث فشل الرمز، فقد انتظرت حتى الآن لإعلان إجابة مقبولة.لقد قمت بتغيير الكود إلى ما يلي:

File parentFolder = new File(targetPath);
... do some checks on parentFolder here ...
File targetFile = new File(parentFolder, filename);
targetFile.createNewFile();
fileInputStream = new FileInputStream(fileToCopy);
fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[64*1024];
int i = 0;
while((i = fileInputStream.read(buffer)) != -1) {
    fileOutputStream.write(buffer, 0, i);
}

بعد ذلك نجح المستخدم في الإبلاغ عن المشكلة.

لذا يبدو أن إجابة ألكساندر قد نجحت في الحيلة - على الرغم من أنني أستخدم مُنشئًا مختلفًا قليلاً عما قدمه، ولكن على نفس المنوال.

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

بالمناسبة.كان التسجيل في مكانه وبدا المسار المسجل جيدًا - آسف لعدم ذكر ذلك.لقد اعتبرت ذلك أمرا مفروغا منه ووجدت أنه يعقد الكود في السؤال دون داع.

شكرا على الإجابات المفيدة.

خطأ مشابه جدًا:- "...java.io.IOException:تم إنشاء اسم الملف أو اسم الدليل أو بناء جملة تسمية مستوى الصوت "في Eclipse بالنسبة لي عندما كان إعداد Home Tomcat قد كان للاضتراب التدريبي.

التعديل الطفيف المقترح في: - http://www.coderanch.com/t/556633/Tomcat/java-io-IOException-filename-directoryثابت بالنسبة لي.

قم بإزالة أي أحرف خاصة في اسم الملف/المجلد في المسار الكامل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top