سؤال

أنا هافا برنامج Java يحتاج إلى مراقبة شجرة دليل للتغييرات. لدي رمز JNI الذي يستخدم ReadDirectoryChangesW(). وبعد يتم فتح الدليل مثل:

HANDLE dirHandle = CreateFile(
    path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
);

ثم تمر dirHandle ل ReadDirectoryChangesW(). وبعد كل هذا يعمل بشكل جيد.

المشكلة هي أن الأجزاء الأخرى من التعليمات البرمجية (على جانب Java) File.setLastModified() إلى "لمس" الملفات أو الدلائل (تحديث الطوابع الزمنية "لتكون" الآن "). هذا يعمل بشكل عام؛ ومع ذلك، فقد فشل عندما حاول "لمس" الدليل الذي تم فتحه باستخدام CreateFile().

لمعرفة خطأ Windows في الواقع، نظرت إلى مصدر JDK ل File.setLastModified() وإعادة تشغيله في الرمز الخاص بي مع إضافة طباعة الخطأ من GetLastError(); ؛ الخطأ هو:

ERROR_SHARING_VIOLATION (error 32)
"The process cannot access the file because it is being used by another process."

ماهذا الهراء؟ انها ال نفس معالجة. حتى مرت FILE_SHARE_READ و FILE_SHARE_WRITE ل CreateFile().

هل هناك طريقة لجعل هذا العمل؟

مزيد من المعلومات

تنفيذ التعليمات البرمجية الأصلية File.setLastModified() في jdk يفعل:

h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);

إذا قمت بتغيير الأول 0 ل FILE_SHARE_READ | FILE_SHARE_WRITE, كل شيء يعمل. لذلك يبدو أن تطبيق JDK مكسور قليلا. :(

لذلك يصبح سؤالي الآن: هل هناك طريقة لجعل هذا العمل دون الحاجة إلى استخدام تنفيذي (إعادة) الخاص بي File.setLastModified()?

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

المحلول

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

عن طريق فتح الدليل مع dwShareMode اضبط jdk، في الواقع، سؤاله، يسجل الوصول الحصري، والذي سيؤدي إلى فشل أي محاولة وصول أخرى مع خطأ بمشاركة مخالفة. ينطبق هذا بالتساوي على الوصول إلى العمليات الأخرى ومن خلال العملية الخاصة بك.

ال CreateFile توثيق يصف dwShareMode معامل:

إذا كانت هذه المعلمة صفرية ويعمل CreateFile، فلا يمكن مشاركت الملف أو الجهاز ولا يمكن فتحه مرة أخرى حتى يتم إغلاق المقبض إلى الملف أو الجهاز.

لا يمكنك طلب وضع المشاركة الذي يتعارض مع وضع الوصول المحدد في طلب موجود يحتوي على مقبض مفتوح. CreateFile سوف تفشل و GetLastError وظيفة سوف تعود ERROR_SHARING_VIOLATION.

لذلك، يبدو أنك قد أجبت على سؤالك الخاص: تحتاج إلى مخصص setLastModified الوظيفة التي تحدد FILE_SHARE_READ | FILE_SHARE_WRITE عند الوصول إلى الدليل.

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