File.exists () ส่งคืนเท็จเมื่อมีไฟล์อยู่


91

ฉันพบข้อผิดพลาดดูเหมือนจะไม่พบเหตุผลใด ๆ ที่อยู่เบื้องหลัง ฉันมีอ็อบเจ็กต์ไฟล์ซึ่งสร้างขึ้นในลักษณะนี้:

File file = new File("utilities/data/someTextFile.txt");

จากนั้นฉันก็ทำfile.exists()และมันจะกลับมาfalse(!?) หากไม่พบไฟล์แสดงว่าฉันกำลังเข้าสู่f.getAbsolutePath()ไฟล์ เมื่อฉันมองไปที่เส้นทางดูเหมือนว่าตกลง ฉันสามารถคัดลอกและวางเส้นทางทั้งหมดลงในหน้าต่าง "Run" ใน Windows และไฟล์จะเปิดขึ้นได้ดี

ไฟล์นี้มีอยู่ตลอดเวลาและจะไม่ถูกลบหรือเปลี่ยนแปลงในระหว่างการเรียกใช้แอปพลิเคชันของฉัน มันอยู่ที่เครื่องในท้องถิ่น

สิ่งนี้ดูเหมือนจะเกิดขึ้นในบางสถานการณ์เท่านั้น ฉันสามารถทำซ้ำข้อผิดพลาดได้ตลอดเวลา แต่ฉันแน่ใจว่าเส้นทางของอ็อบเจ็กต์ไฟล์ไม่ได้เปลี่ยนแปลงไปจากการกระทำที่ฉันทำเพื่อสร้างความผิดพลาดอีกครั้ง

อะไรทำให้file.exists()คืนค่าเท็จได้ สิ่งนี้เกี่ยวข้องกับการอนุญาตหรือการล็อกไฟล์ ฯลฯ หรือไม่?


ดังนั้นเป็นไปได้ไหมที่จะอ่านจากไฟล์แม้ว่าจะมีอยู่ () ส่งคืนเท็จ?
Harry Lime

ใช่ฉันสามารถอ่านจากไฟล์ได้แม้ว่าจะมีอยู่ () ส่งคืนเท็จ
atsjoo

1
อะไรคือสิ่งที่จำเป็นในการสร้างความผิดพลาดซ้ำ?
user85421

1
สิ่งนี้อยู่ในแอปพลิเคชันที่เรียกใช้ฟังก์ชันที่เขียนใน matlab และรวบรวมลงในแอปพลิเคชัน java ดูเหมือนว่าฟังก์ชัน matlab ที่เปลี่ยน "ไดเรกทอรีปัจจุบัน" ทำให้เกิดปัญหาขึ้น ฉันใช้พา ธ สัมบูรณ์ในการสร้างอ็อบเจกต์ไฟล์ดังนั้นนี่จึงไม่น่าจะเป็นปัญหา แต่ดูเหมือนจะเป็น แน่นอนฉันได้ตรวจสอบเส้นทางสัมบูรณ์ของอ็อบเจ็กต์ไฟล์แล้วและถูกต้อง (เช่นเดียวกับก่อนหน้าที่ฟังก์ชัน matlab เปลี่ยนไดเร็กทอรีปัจจุบัน)
atsjoo

7
คุณมีโอกาสทำงานกับรีโมตไดเร็กทอรี (เช่น NFS mount) หรือไม่?
Tomer Gabel

คำตอบ:


42

ฉันเห็นสถานการณ์ต่อไปนี้ใน Windows 7:

file.exists() == false
file.getAbsoluteFile().exists() == true

ไฟล์ที่เป็นปัญหาคือ "var \ log" พา ธ สัมบูรณ์อ้างถึงไฟล์ที่มีอยู่ซึ่งอยู่ในไดเร็กทอรีย่อยปกติ (ไม่ใช่ที่เก็บเสมือน) สิ่งนี้เห็นได้จาก IDE


17
ฉันเพิ่งคิดออก: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 เห็นได้ชัดว่าการดำเนินการที่ทำงานบนไฟล์ได้รับการแก้ไขกับไดเร็กทอรีปัจจุบันในขณะที่ getAbsolutePath แก้ไขกับ user.dir หากสองเส้นทางนี้ไม่ตรงกันคุณจะได้ผลลัพธ์ที่ขัดแย้งกัน ปีศาจ!
Roman Zenka

3
ฉันมีปัญหาเดียวกันแน่นอนฉันพยายามใช้ทั้งสองวิธีเพื่อตรวจสอบว่ามีไฟล์อยู่หรือไม่และยังคงเป็นเท็จใน Windows 7 เท่านั้น! ความคิดใด ๆ ?
Dejell

@Odelya: คุณใช้ IDE อะไร? -Duser.dir ของคุณตั้งค่าเป็นอะไร ปัญหาของฉันเกิดจากการตั้งค่า -Duser.dir ไปยังไดเร็กทอรีอื่นที่ไม่ใช่ไดเร็กทอรีที่ใช้งานได้ในปัจจุบัน
Roman Zenka

1
สำหรับใครก็ตามที่ทำงานกับ Dynamic Web Project การใช้ file.exists () จะทำให้เกิดข้อยกเว้นให้ใช้ file.getAbsoluteFile () มีอยู่ () เพื่อตรวจสอบไฟล์ในไดเรกทอรี WEB-INF (เคล็ดลับทั่วไปไม่ใช่เฉพาะ Windows 7 ).
PS

พิจารณาสร้าง QA แยกต่างหากสำหรับคำตอบและความคิดเห็นนี้
Bato-Bair Tsyrenov

17

ดูเหมือนว่าจะมีความแตกต่างเกี่ยวกับวิธีระบุพา ธ ใน Java

ตัวอย่างเช่นหากเส้นทางของไฟล์ถูกระบุเป็นfile:/C:/DEV/test.txtแล้ว

File f = new File(filename);
f.exists();

falseจะกลับมา เส้นทางอาจใช้ได้ใน explorer หรือในเบราว์เซอร์ แต่เป็น URL ไม่ใช่เส้นทางไฟล์ที่สมบูรณ์

แต่ในทางกลับกันหากระบุเส้นทางไฟล์ไว้C:/DEV/test.txtแล้ว

File f = new File(filename);
f.exists();

จะกลับมาtrueเนื่องจากเส้นทางไม่ใช่ URL แต่เป็นเส้นทางที่แน่นอน

ด้วยSpring Frameworkนั่นคือสิ่งที่ResourceUtils.getFile(filename)ทำ - โดยที่ชื่อสามารถเป็น URL หรือพา ธ ไฟล์สัมบูรณ์


5
ฉันไม่คาดหวังว่าfile:/C:/DEV/test.txtจะทำงานเป็นชื่อพา ธ เป็น URL ไม่ใช่ชื่อพา ธ ในขณะที่บางคนทำผิดพลาดนี้ไม่มีหลักฐานว่า OP มี ...
Stephen C

15

หากกระบวนการไม่มีสิทธิ์ในการบอกว่ามีไฟล์อยู่หรือไม่ระบบจะส่งคืนเท็จ อาจเป็นไปได้ที่จะเปิดไฟล์ แต่ไม่สามารถบอกได้ด้วยวิธีการปกติหากมีอยู่


21
น่าสนใจ. คุณสามารถขยายสิ่งนี้ได้หรือไม่? คุณมีสิทธิ์เฉพาะใดในใจ
Clément

ที่นี่สามารถเป็น java.nio.file.AccessDeniedException ความสามารถในการบล็อกเพื่อเข้าถึงการมีอยู่ของไฟล์ / dir ตัวอย่างเช่นหากคุณเปิด dir ไว้ใน FAR หรือ file explorer อื่น ๆ จากนั้นลบ dir ด้วยไฟล์ที่ซ้อนกันทั้งหมดและตรวจสอบการมีอยู่ของ dir นี้จากนั้นคุณจะได้รับ AccessDeniedException (ขยาย IOException) สำหรับไฟล์ชั่วคราวที่เก็บไว้สำหรับคุณ ในกรณีนี้ Files.exists จะส่งคืนเท็จสำหรับ IOException
beluha

11

คำตอบข้างต้นไม่ได้ช่วยอะไรในกรณีของฉัน ตามที่ระบุไว้ข้างต้นฉันมี:

file.exists() => false
file.getAbsoluteFile().exists => true

สาเหตุที่แท้จริงคือเจ้าของเครื่องWindows 7ได้แก้ไขรีจิสทรีสำหรับ CMD เพื่อให้เรียกใช้คำสั่งโดยอัตโนมัติเพื่อเปิดใช้งานในไดเร็กทอรีเฉพาะเพื่อทำงานกับ Python การแก้ไขนี้ทำให้โค้ดJava 1.6พิการซึ่งเห็นได้ชัดว่าใช้CMDบนWindowsสำหรับการทำงานของไฟล์บางไฟล์เช่นexists(). การกำจัดการทำงานอัตโนมัติจากรีจิสทรีช่วยแก้ปัญหาได้


1
3.5 ปีต่อมาและฉันพบปัญหาเดียวกัน ฉันมีสคริปต์การทำงานอัตโนมัติที่ตั้งค่าเพื่อกำหนดค่าตัวแปรสภาพแวดล้อมทุกครั้งที่เปิด cmd.com มันไม่ได้เปลี่ยนไดเร็กทอรีปัจจุบัน - มีเพียงมาโคร doskey บางตัวและตัวแปรสภาพแวดล้อมบางตัว ฉันลบการทำงานอัตโนมัติและเพียงแค่เรียกใช้คำสั่งในไฟล์ด้วยตนเองและทันใดนั้น File.exists () ก็ทำงานได้อย่างถูกต้อง
Homr Zodyssey

1
OMG มันใช้งานได้จริง (ทั้งสองอย่าง) ฉันแค่ตรวจสอบไฟล์ที่ไม่ถูกต้องและเจอคำถามนี้เพื่อค้นหาว่าทำไมไม่มีอะไรทำงานให้ฉัน :) BTW ดูเหมือนว่า()จะหายไปในบรรทัดที่สองหลังจากexists; )
RAM237

3

เมื่อ ["ซ่อนนามสกุลสำหรับประเภทไฟล์ที่รู้จัก"] ถูกตรวจสอบว่า windows เปิด "t.txt.txt" เมื่อพิมพ์ "t.txt" ใน [explorer] / [run windows] แต่โดยทางโปรแกรมไม่ได้


1
ฉันมีปัญหานี้และปัญหาคือฉันสร้างไฟล์ txt ซึ่งเรียกว่า 'testFile.txt' ใน C: \ test ฉันอ้างถึงไฟล์นี้โดยใช้เส้นทาง C: \ test \ testFile.txt ซึ่งไม่ได้ผล เป็นเพราะไฟล์ได้รับการบันทึกเป็น testFile.txt.txt แล้วดังนั้นจึงมีการโหวตขึ้นในโซลูชันข้างต้น (คำถามเก่า แต่ไม่มีคำตอบที่ยอมรับ!)
Theblacknight

พระเจ้า Windows ห่วยมาก
aafc

3

เห็นได้ชัดว่ามีสาเหตุที่เป็นไปได้หลายประการและคำตอบก่อนหน้านี้บันทึกไว้เป็นอย่างดี แต่นี่คือวิธีที่ฉันแก้ไขปัญหานี้ในกรณีเฉพาะ:

นักเรียนคนหนึ่งของฉันมีปัญหานี้และฉันเกือบจะฉีกผมพยายามคิดออก ปรากฎว่าไม่มีไฟล์อยู่แม้ว่ามันจะดูเหมือนมันก็ตาม ปัญหาคือ Windows 7 ถูกกำหนดค่าให้ "ซ่อนนามสกุลไฟล์สำหรับประเภทไฟล์ที่รู้จัก" ซึ่งหมายความว่าหากไฟล์มีชื่อว่า "data.txt" ชื่อไฟล์จริงคือ "data.txt.txt"

หวังว่านี่จะช่วยให้คนอื่น ๆ ช่วยตัวเองได้บ้าง


ฉันไม่คิดว่านี่เป็นปัญหาในกรณีของฉัน ดังที่ได้กล่าวไว้ในคำถามของฉัน: "ฉันสามารถคัดลอก - วางเส้นทางทั้งหมดลงในหน้าต่าง" Run "ใน Windows และไฟล์จะเปิดขึ้นได้ดี" ซึ่งหมายความว่าไฟล์นั้นมีอยู่จริง
atsjoo

3

new Fileคำสั่งเพียงแค่สร้างตัวอย่างของไฟล์โดยใช้ชื่อเส้นทางรับ มันไม่ได้สร้างไฟล์ในฮาร์ดไดรฟ์จริงๆ

ถ้าคุณพูด

File file = new File ("path");
file.exists() 

สิ่งนี้สามารถคืนค่าจริงได้ก็ต่อเมื่อมีไฟล์ที่มีเส้นทางเดียวกันอยู่แล้ว หากคุณตั้งใจจะตรวจสอบไฟล์เดียวกันที่ประกาศในบรรทัดแรกคุณอาจต้องใช้วิธีนี้

File file = new File ("path");
file.createNewFile();
file.exists();

ตอนนี้จะกลับมาเป็นจริง


คำอธิบายเล็ก ๆ : การเรียกตัวสร้างทุกครั้งโดยใช้คีย์เวิร์ดใหม่จะสร้างอ็อบเจกต์ - เช่นเดียวกับในกรณีนี้อ็อบเจ็กต์ที่อธิบายโดยคลาสซึ่งชื่อคือไฟล์ ดังนั้นไม่ใช่ตัวอย่างของ File! = descriptors :)
ceph3us

3

หากคุณไม่ต้องการจัดการกับการเรียก getAbsoluteFile () ทุกครั้งที่คุณต้องเรียกใช้เมธอดคุณควรสร้างอินสแตนซ์ไฟล์ของคุณด้วยพา ธ สัมบูรณ์ สิ่งนี้ควรทำเคล็ดลับ:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

ฉันขอแนะนำให้ล้อมรอบด้วยบล็อกลองจับ BTW


2

เพื่อสรุปปัญหาโดยทั่วไปปัญหาเกิดขึ้นขณะแปลง URL / URI เป็นเส้นทางภายในเครื่อง

Example: URL url = file:/D:/code%20repo%20sample/sample.txt

// To remove url reference
String localPath = url.getPath();  
> /D:/code%20repo%20sample/sample.txt

// Decoding reserved characters in url from hexadecimal to character
URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
> /D:/code repo sample/sample.txt

หวังว่านี่จะช่วยได้


0

ตอบดีทุกคน ฉันพบว่าสิ่งนี้ดูเหมือนจะมีปัญหากับ Java ที่เข้าถึงC:ไดเรกทอรีรากบน Windows ไดเร็กทอรีอื่น ๆ ควรจะใช้ได้ แต่ด้วยเหตุผลบางประการการกล่าวถึงโดยเฉพาะC:\หรือC:หรือC:/อาจให้ข้อผิดพลาด ฉันได้แก้ไขปัญหาที่คล้ายกันนี้แล้วโดยวางกับดักพูดถึงnew File("C:");และแทนที่ด้วยใหม่File(System.getProperty("file.separator"));หรือคุณควรจะสามารถฮาร์ดโค้ด "\" แทนการพูดว่า "c:" เป็นไดเร็กทอรีไฟล์ของคุณและมันอาจได้ผล ไม่สวยหรู แต่ได้งานทำสำหรับฉันในโครงการนี้

ฉันหวังว่ามันจะช่วยได้ อาจไม่ใช่วิธีแก้ปัญหาที่ถูกต้อง แต่อย่างน้อยมันก็ใช้ได้ผลสำหรับฉัน JRE 1.6, Win 7ฉัน ไชโย!

ด้วยความเคารพ

@ ช่างไม้ 1010


0

หากสถานการณ์ที่ล้มเหลวเกี่ยวข้องกับการเรียกใช้งานในฐานะผู้ใช้รายอื่นและคุณใช้ Windows Vista / Windows 7 อาจเกิดจาก VirtualStore ซึ่งเป็นกลไกที่ Windows ปล่อยให้ผู้ใช้ที่ไม่มีสิทธิ์ "เขียน" วางตำแหน่งที่ปกติไม่สามารถทำได้ อย่างไรก็ตามการเปลี่ยนแปลงจะถูกเก็บไว้ใน "% USERPROFILE% \ AppData \ Local \ VirtualStore \" ซึ่งเป็นส่วนตัวสำหรับบัญชีผู้ใช้แต่ละบัญชี


1
ฉันใช้ windows xp x86
atsjoo

0

เมื่อไม่มีสิ่งใดจากเบื้องบนได้ผลสำหรับฉันฉันจึงพยายาม

filePath = filePath.trim();

สิ่งนี้จะล้างสตริงของคุณจากอักขระที่ไม่ต้องการ


0

FWIW มีอีกสถานที่หนึ่งที่เกิดเหตุการณ์นี้ขึ้น

File("")คือชื่อของไดเร็กทอรีปัจจุบัน มักจะกลับมาFile("").exists() เคล็ดลับการทำงานและจะกลับมา(ทะนงไดเรกทอรีปัจจุบันมีอยู่ ... )falseFile(("").getAbsoluteFile().exists()true


-1

ฉันเพิ่งเจอปัญหาเดียวกันนี้ สิ่งที่ฉันทำคือถอนการติดตั้ง Netbeans ลบโฟลเดอร์ netbeans จากไดรฟ์ C ไฟล์โปรแกรมอัพเดต programData แทบทุกที่ จากนั้นติดตั้งใหม่ ตอนนี้ใช้งานได้ดี. อย่าลืมสำรองข้อมูลโฟลเดอร์โครงการ netbeans ก่อนดำเนินการข้างต้น

หวังว่าจะช่วยได้


-1

ด้วย IDE บางอย่าง (อาจเป็น) และหรือกับระบบปฏิบัติการบางอย่าง (เช่นหน้าต่าง) โดยค่าเริ่มต้นจะไม่มีสิทธิ์เขียนไฟล์ ดังนั้นหากคุณพยายามทำ file.exists () มันจะแสดงว่าคุณเป็นเท็จ เพื่อแก้ไขปัญหานี้ให้ทำดังนี้

ถ้าตัวแปร ref ของคุณสำหรับ File คือ f ตัวอย่างเช่น File f = new File ("path");

เพื่อให้มันใช้งานได้ให้เลือก f ด้วยเมาส์จากนั้นไปที่เมนูค้นหา> การเข้าถึงการเขียน> พื้นที่ทำงาน หวังว่าจะได้ผลนะ


-2

ฉันคิดว่าคุณควรใช้แบ็กสแลชแทนดังนี้:

ไฟล์ไฟล์ = ไฟล์ใหม่ ("C: \\ User \\ utilities \\ data \\ someTextFile.txt"); (สองแบ็กสแลชไม่ใช่พิมพ์ผิด)

ควรแก้ปัญหา :)


3
ฉันคิดว่าปัญหานี้เกี่ยวข้องกับเส้นทางสัมบูรณ์เทียบกับเส้นทางสัมพัทธ์มากกว่า เครื่องหมายทับใช้ได้ใน Java แม้กระทั่งสำหรับพา ธ Windows
рüффп
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.