כיצד לקרוא קובץ ב- Java

1. סקירה כללית

במדריך זה נחקור דרכים שונות לקרוא מתוך קובץ ב- Java.

ראשית נראה כיצד לטעון קובץ משביל הכיתה, כתובת URL או מקובץ JAR באמצעות שיעורי Java רגילים.

שנית, נראה כיצד לקרוא איתו את התוכן BufferedReader, סוֹרֵק, StreamTokenizer, DataInputStream, SequenceInputStream, ו FileChannel. כמו כן, נדון כיצד לקרוא קובץ מקודד UTF-8.

לבסוף נחקור את הטכניקות החדשות לטעינת וקריאת קובץ ב- Java 7 ו- Java 8.

מאמר זה הוא חלק מסדרת "Java - Back to Basic" כאן בבלדונג.

2. התקנה

2.1 קובץ קלט

ברוב הדוגמאות במאמר זה נקרא קובץ טקסט עם שם קובץ fileTest.txt המכיל שורה אחת:

שלום עולם!

בכמה דוגמאות נשתמש בקובץ אחר. במקרים אלה נזכיר את הקובץ ואת תוכנו במפורש.

2.2 שיטת עוזר

נשתמש במכלול של דוגמאות בדיקה תוך שימוש בשיעורי ליבה של Java בלבד, ובמבחנים נשתמש בקביעות באמצעות התאמות Hamcrest.

בדיקות יחלקו משותף readFromInputStream שיטה שהופכת InputStream ל חוּט לקביעת תוצאות קלות יותר:

מחרוזת פרטית readFromInputStream (InputStream inputStream) זורק IOException {StringBuilder resultStringBuilder = StringBuilder חדש (); נסה (BufferedReader br = BufferedReader חדש (InputStreamReader חדש (inputStream))) {קו מחרוזת; ואילו ((line = br.readLine ())! = null) {resultStringBuilder.append (line) .append ("\ n"); }} להחזיר resultStringBuilder.toString (); }

שימו לב שיש דרכים אחרות להשגת אותה תוצאה. תוכל לעיין במאמר זה בכמה חלופות.

3. קריאת קובץ משביל הכיתה

3.1. שימוש בג'אווה רגילה

חלק זה מסביר כיצד לקרוא קובץ זמין על מסלול כיתה. נקרא את " fileTest.txt ”זמין תחת src / main / resources :

@Test ציבורי בטל givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData () {String expectData = "שלום עולם!"; קלאס קלאס = FileOperationsTest.class; InputStream inputStream = clazz.getResourceAsStream ("/ fileTest.txt"); נתוני מחרוזת = readFromInputStream (inputStream); Assert.assertThat (data, containString (expectData)); }

בקטע הקוד שלמעלה השתמשנו במחלקה הנוכחית לטעינת קובץ באמצעות getResourceAsStream שיטה והעביר את הנתיב המוחלט של הקובץ לטעינה.

אותה שיטה זמינה ב- ClassLoader למשל גם:

ClassLoader classLoader = getClass (). GetClassLoader (); InputStream inputStream = classLoader.getResourceAsStream ("fileTest.txt"); נתוני מחרוזת = readFromInputStream (inputStream);

אנו משיגים את classLoader של הכיתה הנוכחית באמצעות getClass (). getClassLoader () .

ההבדל העיקרי הוא שכאשר משתמשים ב- getResourceAsStream על ClassLoader למשל, מתייחסים לנתיב כאל מוחלט החל משורש שביל הכיתה.

כאשר משתמשים נגד א מעמד למשל , הנתיב יכול להיות יחסי לחבילה, או נתיב מוחלט, שרומז על ידי הנטייה המובילה.

כמובן, שימו לב שבפועל, תמיד צריך לסגור זרמים פתוחים, כמו ה InputStream בדוגמה שלנו:

InputStream inputStream = null; נסה את {File file = File חדש (classLoader.getResource ("fileTest.txt"). getFile ()); inputStream = FileInputStream חדש (קובץ); // ...} סוף סוף {if (inputStream! = null) {נסה {inputStream.close (); } לתפוס (IOException e) {e.printStackTrace (); }}}

3.2. משתמש ב commons-io סִפְרִיָה

אפשרות נפוצה נוספת היא שימוש ב- FileUtils הכיתה של commons-io חֲבִילָה:

@Test הציבור בטל givenFileName_whenUsingFileUtils_thenFileData () {String expectData = "שלום, עולם!"; ClassLoader classLoader = getClass (). GetClassLoader (); קובץ קובץ = קובץ חדש (classLoader.getResource ("fileTest.txt"). GetFile ()); נתוני מחרוזת = FileUtils.readFileToString (קובץ, "UTF-8"); assertEquals (expectData, data.trim ()); }

כאן אנו עוברים את קוֹבֶץ להתנגד לשיטה readFileToString () שֶׁל FileUtils מעמד. מחלקת כלי עזר זו מצליחה לטעון את התוכן ללא צורך בכתיבת קוד Boilerplate כדי ליצור InputStream למשל ולקרוא נתונים.

אותה ספרייה מציעה גם את IOUtilsמעמד:

@Test ציבורי בטל givenFileName_whenUsingIOUtils_thenFileData () {String expectData = "שלום עולם!"; FileInputStream fis = FileInputStream חדש ("src / test / resources / fileTest.txt"); נתוני מחרוזת = IOUtils.toString (fis, "UTF-8"); assertEquals (expectData, data.trim ()); }

כאן אנו עוברים את FileInputStream להתנגד לשיטה toString () שֶׁל IOUtils מעמד. מחלקת כלי עזר זו מצליחה לטעון את התוכן ללא צורך בכתיבת קוד Boilerplate כדי ליצור InputStream למשל ולקרוא נתונים.

4. קריאה עם BufferedReader

כעת נתמקד בדרכים שונות לנתח את תוכן הקובץ.

נתחיל בדרך פשוטה לקרוא מתוך קובץ באמצעות BufferedReader:

@ מבחן ציבורי בטל כאשר ReadWithBufferedReader_thenCorrect () זורק IOException {String expected_value = "שלום עולם!"; קובץ מחרוזת; BufferedReader reader = BufferedReader חדש (FileReader חדש (קובץ)); מחרוזת currentLine = reader.readLine (); reader.close (); assertEquals (expect_value, currentLine); }

ציין זאת קריאת שורה() יחזור ריק כאשר מגיעים לסוף הקובץ.

5. קריאה מקובץ באמצעות Java NIO

ב- JDK7 חבילת ה- NIO עודכנה משמעותית.

בואו נסתכל על דוגמא באמצעות קבצים הכיתה וה readAllLines שיטה. ה readAllLines השיטה מקבלת א נָתִיב.

נָתִיב בכיתה יכול להיחשב כשדרוג של java.io. קובץ עם כמה פעולות נוספות במקום.

5.1. קריאת קובץ קטן

הקוד הבא מראה כיצד לקרוא קובץ קטן באמצעות הקובץ החדש קבצים מעמד:

@Test הציבור בטל כאשרReadSmallFileJava7_thenCorrect () זורק IOException {String expect_value = "שלום, עולם!"; נתיב נתיב = Paths.get ("src / test / resources / fileTest.txt"); מחרוזת קריאה = Files.readAllLines (נתיב) .get (0); assertEquals (צפוי_ערך, קרא); }

שים לב שאתה יכול להשתמש ב- readAllBytes () גם אם אתה זקוק לנתונים בינאריים.

5.2. קריאת קובץ גדול

אם אנחנו רוצים לקרוא קובץ גדול עם קבצים בכיתה, אנחנו יכולים להשתמש ב- BufferedReader:

הקוד הבא קורא את הקובץ באמצעות החדש קבצים כיתה ו BufferedReader:

@Test הציבור בטל כאשרReadLargeFileJava7_thenCorrect () זורק IOException {String expect_value = "שלום עולם!"; נתיב נתיב = Paths.get ("src / test / resources / fileTest.txt"); קורא BufferedReader = Files.newBufferedReader (נתיב); קו מחרוזת = reader.readLine (); assertEquals (expect_value, line); }

5.3. קריאת קובץ באמצעות Files.lines ()

JDK8 מציע את שורות() שיטה בתוך קבצים מעמד. זה מחזיר א זרם של אלמנטים מחרוזת.

בואו נסתכל על דוגמה כיצד לקרוא נתונים לבתים ולפענח באמצעות ערכת UTF-8.

הקוד הבא קורא את הקובץ באמצעות החדש Files.lines ():

@Test הציבור בטל givenFilePath_whenUsingFilesLines_thenFileData () {String expectData = "שלום עולם!"; נתיב נתיב = Paths.get (getClass (). GetClassLoader () .getResource ("fileTest.txt"). ToURI ()); זרם שורות = Files.lines (נתיב); נתוני מחרוזת = lines.collect (Collectors.joining ("\ n")); lines.close (); Assert.assertEquals (expectData, data.trim ()); }

שימוש בזרם עם ערוצי IO כמו פעולות קבצים, עלינו לסגור את הזרם במפורש באמצעות ה- סגור() שיטה.

כפי שאנו רואים, קבצים API מציע דרך קלה נוספת לקרוא את תוכן הקובץ לתוך חוּט.

בחלקים הבאים, בואו נסתכל על שיטות אחרות, פחות נפוצות לקריאת קובץ, שעשויות להיות מתאימות במצבים מסוימים.

6. קריאה עם סוֹרֵק

לאחר מכן, בואו נשתמש ב- סוֹרֵק לקריאה מהקובץ. כאן נשתמש במרחב לבן כמפריד:

@Test ציבורי בטל כאשר ReadWithScanner_thenCorrect () זורק IOException {String file = "src / test / resources / fileTest.txt"; סורק סורק = סורק חדש (קובץ חדש (קובץ)); scanner.useDelimiter (""); assertTrue (scanner.hasNext ()); assertEquals ("שלום,", scanner.next ()); assertEquals ("עולם!", scanner.next ()); scanner.close (); }

שים לב שמפריד ברירת המחדל הוא השטח הלבן, אך ניתן להשתמש במפרידים מרובים עם a סוֹרֵק.

מחלקת הסורקים שימושית בעת קריאת תוכן מהקונסולה, או כאשר התוכן מכיל ערכים פרימיטיביים, עם תיחום ידוע (למשל: רשימה של מספרים שלמים המופרדים על ידי רווח).

7. קריאה עם StreamTokenizer

לאחר מכן, בואו נקרא קובץ טקסט לאסימונים באמצעות a StreamTokenizer.

אופן פעולת האסימון הוא - ראשית עלינו להבין מהו האסימון הבא - מחרוזת או מספר; אנו עושים זאת על ידי התבוננות ב tokenizer.ttype שדה.

לאחר מכן נקרא את האסימון בפועל על סמך סוג זה:

  • tokenizer.nval - אם הסוג היה מספר
  • tokenizer.sval - אם הסוג היה מחרוזת

בדוגמה זו נשתמש בקובץ קלט אחר אשר פשוט מכיל:

שלום 1

הקוד הבא קורא מהקובץ גם את המחרוזת וגם את המספר:

@Test ציבורי בטל כאשר ReadWithStreamTokenizer_thenCorrectTokens () זורק IOException {String file = "src / test / resources / fileTestTokenizer.txt"; FileReader reader = FileReader חדש (קובץ); טוקניזר StreamTokenizer = StreamTokenizer חדש (קורא); // tokenizer tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_WORD, tokenizer.ttype); assertEquals ("שלום", tokenizer.sval); // tokenizer tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_NUMBER, tokenizer.ttype); assertEquals (1, tokenizer.nval, 0.0000001); // tokenizer 3 tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_EOF, tokenizer.ttype); reader.close (); }

שים לב כיצד נעשה שימוש בסוף אסימון הקובץ.

גישה זו שימושית לניתוח זרם קלט לאסימונים.

8. קריאה עם DataInputStream

אנחנו יכולים להשתמש DataInputStream לקריאת סוג נתונים בינארי או פרימיטיבי מקובץ.

המבחן הבא קורא את הקובץ באמצעות DataInputStream:

@ מבחן ציבורי בטל כאשר ReadWithDataInputStream_thenCorrect () זורק IOException {String expectValue = "שלום עולם!"; קובץ מחרוזת; תוצאת מחרוזת = null; קורא DataInputStream = DataInputStream חדש (FileInputStream חדש (קובץ)); int nBytesToRead = reader.available (); אם (nBytesToRead> 0) {בתים [] בתים = בתים חדשים [nBytesToRead]; reader.read (בתים); תוצאה = מחרוזת חדשה (בתים); } assertEquals (expectValue, result); }

9. קריאה עם FileChannel

אם אנו קוראים קובץ גדול, FileChannel יכול להיות מהיר יותר מאשר IO רגיל.

הקוד הבא קורא בתים נתונים מהקובץ באמצעות FileChannel ו RandomAccessFile:

@ מבחן ציבורי בטל כאשר ReadWithFileChannel_thenCorrect () זורק IOException {String expect_value = "שלום עולם!"; קובץ מחרוזת = "src / test / resources / fileTest.txt"; קורא RandomAccessFile = RandomAccessFile חדש (קובץ, "r"); ערוץ FileChannel = reader.getChannel (); int bufferSize = 1024; אם (bufferSize> channel.size ()) {bufferSize = (int) channel.size (); } Buff buff = ByteBuffer.allocate (bufferSize); channel.read (חובב); buff.flip (); assertEquals (expect_value, מחרוזת חדשה (buff.array ())); channel.close (); reader.close (); }

10. קריאת קובץ UTF-8 מקודד

עכשיו, בואו נראה איך לקרוא קובץ מקודד UTF-8 באמצעות BufferedReader. בדוגמה זו נקרא קובץ המכיל תווים סיניים:

@Test ציבורי בטל כאשרReadUTFEncodedFile_thenCorrect () זורק IOException {String expected_value = "青 空"; קובץ מחרוזת = "src / test / resources / fileTestUtf8.txt"; BufferedReader reader = BufferedReader חדש (InputStreamReader חדש (FileInputStream חדש (קובץ), "UTF-8")); מחרוזת currentLine = reader.readLine (); reader.close (); assertEquals (expect_value, currentLine); }

11. קריאת תוכן מ- URL

כדי לקרוא תוכן מכתובת אתר, נשתמש "/כתובת האתר בדוגמה שלנו כ:

@ מבחן פומבי בטל שניתןURLName_whenUsingURL_thenFileData () {String expectData = "Baeldung"; URL urlObject = URL חדש ("/"); URLConnection urlConnection = urlObject.openConnection (); InputStream inputStream = urlConnection.getInputStream (); נתוני מחרוזת = readFromInputStream (inputStream); Assert.assertThat (data, containString (expectData)); }

ישנן גם דרכים אלטרנטיביות להתחברות לכתובת URL. כאן השתמשנו ב- כתובת אתר ו חיבור URLC בכיתה הזמינה ב- SDK הסטנדרטי.

12. קריאת קובץ מתוך JAR

כדי לקרוא קובץ שנמצא בתוך קובץ JAR, נצטרך JAR עם קובץ בתוכו. לדוגמא שלנו נקרא "LICENSE.txt" מ ה "hamcrest-library-1.3.jarקובץ:

@Test ציבורי בטל givenFileName_whenUsingJarFile_thenFileData () {String expectData = "רישיון BSD"; קלאס כיתתי = Matchers.class; InputStream inputStream = clazz.getResourceAsStream ("/ LICENSE.txt"); נתוני מחרוזת = readFromInputStream (inputStream); Assert.assertThat (data, containString (expectData)); }

כאן אנחנו רוצים לטעון LICENSE.txt שנמצא בספריית Hamcrest, אז נשתמש ב- של שידוך כיתה שעוזרת להשיג משאב. ניתן לטעון את אותו הקובץ גם באמצעות הכיתה.

13. מסקנה

כפי שאתה יכול לראות, ישנן אפשרויות רבות לטעינת קובץ ולקריאת נתונים ממנו באמצעות Java רגיל.

אתה יכול לטעון קובץ ממיקומים שונים כמו מסלול כיתה, URL או קבצי צנצנת.

אז אתה יכול להשתמש BufferedReader לקרוא שורה אחר שורה, סוֹרֵק לקרוא באמצעות תוחמים שונים, StreamTokenizer לקרוא קובץ לאסימונים, DataInputStream לקרוא נתונים בינאריים וסוגי נתונים פרימיטיביים, זרם קלט לקשר מספר קבצים לזרם אחד, FileChannel לקרוא מהר יותר מקבצים גדולים וכו '.

אתה יכול למצוא את קוד המקור ברפיו הבא של GitHub.


$config[zx-auto] not found$config[zx-overlay] not found