كيفية معرفة أي موضوع يقفل ملف في جافا؟
-
24-09-2019 - |
سؤال
أحاول حذف ملف قام به مؤشر ترابط آخر داخل برنامجي سابقًا.
أنا غير قادر على حذف الملف ولكني لست متأكدًا من كيفية معرفة مؤشر ترابط قد يستخدم الملف.
فكيف يمكنني معرفة أي موضوع يقفل الملف في جافا؟
المحلول
ليس لدي إجابة مباشرة (ولا أعتقد أن هناك واحدة أيضًا ، يتم التحكم في هذا على مستوى OS (الأصلي) ، وليس على مستوى JVM) ولا أرى أيضًا قيمة الإجابة ( ما زلت لا تستطيع إغلاق الملف برمجياً بمجرد اكتشاف الخيط الذي هو عليه) ، لكنني أعتقد أنك لا تعرف حتى الآن أن عدم القدرة على حذفه عادة ما يكون سببًا عندما لا يزال الملف مفتوحًا. قد يحدث هذا عندما تفعل ليس استدعاء صراحة Closeable#close()
على ال InputStream
, OutputStream
, Reader
أو Writer
الذي تم بناؤه حول File
في السؤال.
العرض التجريبي الأساسي:
public static void main(String[] args) throws Exception {
File file = new File("c:/test.txt"); // Precreate this test file first.
FileOutputStream output = new FileOutputStream(file); // This opens the file!
System.out.println(file.delete()); // false
output.close(); // This explicitly closes the file!
System.out.println(file.delete()); // true
}
بمعنى آخر ، تأكد من أن الكود يعمل بشكل صحيح طوال فترة جافا IO بشكل صحيح إغلاق الموارد بعد الاستخدام. المصطلح الطبيعي هو القيام بذلك في ال try-with-resources
بيان, ، حتى تتأكد من أن الموارد سيتم تحريرها على أي حال ، حتى في حالة وجود IOException
. على سبيل المثال
try (OutputStream output = new FileOutputStream(file)) {
// ...
}
افعلها أي InputStream
, OutputStream
, Reader
و Writer
, ، إلخ. مهما كان ينفذ AutoCloseable
, التي تفتحها نفسك (باستخدام new
الكلمة الرئيسية).
هذا غير مطلوب تقنيًا على بعض التطبيقات ، مثل ByteArrayOutputStream
, ، ولكن من أجل الوضوح ، مجرد الالتزام المصطلح الوثيق في كل مكان لتجنب المفاهيم الخاطئة وإعادة البضائع.
في حال لم تكن على Java 7 أو الأحدث حتى الآن ، فاستخدم أدناه try-finally
المصطلح بدلا من ذلك.
OutputStream output = null;
try {
output = new FileOutputStream(file);
// ...
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}
آمل أن يساعد هذا في ترميم السبب الجذري لمشكلتك الخاصة.
نصائح أخرى
حول هذا السؤال ، أحاول أيضًا معرفة هذه الإجابة ، وأسأل هذا السؤال وابحث عن الإجابة:
في كل مرة عندما قفل موضوع JVM أ ملف على وجه الحصر ، أيضا JVM قفل بعض جاف كائن, ، على سبيل المثال ، أجد في حالتي:
- sun.nio.fs.nativebuffer
- sun.nio.ch.Util $ buffercache
لذا ، فأنت بحاجة فقط إلى العثور على كائن Java المقفل وتحليله وتجد ما هو مؤشر ترابط ملفك.
لست متأكدًا من أنه يعمل إذا فتح ملف فقط (بدون قفل حصريًا) ، لكنني متأكد من أنه يعمل إذا تم قفل الملف بشكل حصري بواسطة Thread (باستخدام java.nio.channels.filelock ، java.nio.channels.filechannel وهكذا على)
مزيد من المعلومات انظر هذا السؤال