מדריך ל- Java OutputStream

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

במדריך זה נחקור פרטים על מחלקת Java OutputStream. אוutputStream הוא מעמד מופשט. זה משמש כ מעמד העל עבור כל הכיתות המייצגות זרם פלט של בתים.

נבדוק מה המשמעות של מילים אלה כמו "פלט" ו"זרם "בהרחבה.

2. מבוא קצר ל- Java IO

OutputStream הוא חלק מ- Java IO API המגדיר שיעורים הנדרשים לביצוע פעולות קלט / פלט בג'אווה. כל אלה ארוזים ב java.io מרחב שמות. זוהי אחת מחבילות הליבה הזמינות ב- Java מאז גרסת 1.0.

החל מ- Java 1.4, יש לנו Java NIO ארוז במרחב השמות java.nio המאפשר פעולות קלט ופלט שאינן חוסמות. אולם אזור המיקוד שלנו למאמר זה הוא ObjectStream כחלק מ- Java IO.

פרטים הקשורים ל- Java IO ו- Java NIO ניתן למצוא כאן.

2.1. קלט ופלט

Java IO בעצם מספק מנגנון לקריאת נתונים ממקור וכתיבת נתונים ליעד. קלט מייצג את המקור ואילו פלט מייצג את היעד כאן.

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

2.2. זרמים

Java IO מספק את הרעיון של זרמים אשר בעצם מייצג זרם רציף של נתונים. זרמים יכולים לתמוך בסוגים רבים ושונים של נתונים כמו בתים, תווים, אובייקטים וכו '.

יתר על כן, חיבור למקור או ליעד הוא מה שזרם מייצג. מכאן הם באים גם InputStream אוֹ OutputStream בהתאמה.

3. ממשקים של OutputStream

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

3.1. סגור

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

3.2. ניתן לסגירה אוטומטית

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

ניתן למצוא פרטים נוספים בנוגע לנסות משאבים כאן.

3.3. ניתן להשטפה

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

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

4. שיטות ב- OutputStream

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

אלה מלבד סגור() ו סומק() שיטות שהיא יורשת מהן סגור ו ניתן להשטפה ממשקים.

4.1. כתוב (int b)

אנו יכולים להשתמש בשיטה זו כדי כתוב בית ספציפי אחד ל- OutputStream. מכיוון שהטיעון "int" כולל ארבעה בתים, כנקודת ההסכם נכתב רק בתים ראשונים של הסדר הנמוך ואת שלושת הבתים מהסדר הגבוה שנותרו והתעלמו מהם:

קובץ חלל סטטי ציבוריOutputStreamByteSingle (קובץ מחרוזת, נתוני מחרוזת) זורק IOException {byte [] bytes = data.getBytes (); נסה (OutputStream out = FileOutputStream חדש (קובץ)) {out.write (בתים [6]); }}

אם אנו מכנים שיטה זו עם נתונים בשם "שלום עולם!", מה שנקבל כתוצאה הוא קובץ עם הטקסט הבא:

W

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

4.2. כתוב (בתים [] b, int off, int אורך)

הגרסה העמוסה הזו של ה- לִכתוֹב() השיטה היא שם כתוב תת רצף של מערך הבתים ל- OutputStream.

הוא יכול לכתוב מספר "אורך" של בתים ממערך הבתים כמפורט על ידי הארגומנט המתחיל בקיזוז שנקבע על ידי "כבוי" למצב OutputStream:

קובץ חלל סטטי ציבוריOutputStreamByteSubSequence (קובץ מחרוזת, נתוני מחרוזת) זורק IOException {בתים [] בתים = data.getBytes (); נסה (OutputStream out = FileOutputStream חדש (קובץ)) {out.write (בתים, 6, 5); }}

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

עוֹלָם

זהו המצע של הנתונים שלנו שמתחילים באינדקס חמש וכוללים חמישה תווים.

4.3. כתוב (בתים [] ב)

זו עוד גרסה עמוסה מדי של ה- לִכתוֹב() שיטה שיכולה כתוב מערך בתים שלם כמפורט בטיעון ל- OutputStream.

יש לזה אותה השפעה כמו קריאה ל כתוב (b, 0, b.lengh):

קובץ חלל סטטי ציבוריOutputStreamByteSequence (קובץ מחרוזת, נתוני מחרוזת) זורק IOException {byte [] bytes = data.getBytes (); נסה (OutputStream out = FileOutputStream חדש (קובץ)) {out.write (בתים); }}

כאשר אנו קוראים לשיטה זו כעת עם אותם נתונים, יש לנו את כל השמות חוּט בקובץ הפלט שלנו:

שלום עולם!

5. מחלקות משנה ישירות של OutputStream

כעת נדון בכמה מתתי הסוגים המוכרים הישירים של OutputStream המייצגים בנפרד סוג נתונים ספציפי אשר ה- OutputStream הם מגדירים.

הם מגדירים את השיטות שלהם לבד מביצוע אלה שעברו בירושה OutputStream.

לא ניכנס לפרטי קבוצות המשנה הללו.

5.1. FileOutputStream

כפי שהשם מרמז, א FileOutputStream הוא an OutputStream לכתוב נתונים ל- a קוֹבֶץ. FileOutputStream, כמו כל אחד אחר OutputStream, יכול לכתוב זרם של בתים גולמיים.

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

5.2. ByteArrayOutputStream

ByteArrayOutputStream הוא הטמעה של OutputStream שיכולים לכתוב נתונים למערך בתים. המאגר ממשיך לגדול כמו ByteArrayOutputStream כותב אליו נתונים.

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

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

5.3. FilterOutputStream

OutputStream כותב בעיקר זרם בתים ליעד, אך הוא יכול גם להפוך את הנתונים לפני שעושים זאת. FilterOutputStream מייצג מעמד-על של כל הכיתות הללו המבצעות טרנספורמציית נתונים ספציפית. FilterOutputStream נבנה תמיד עם קיים OutputStream.

חלק מהדוגמאות של FilterOutputStream הם BufferedOutputStream, CheckedOutputStream, CipherOutputStream, DataOutputStream, DeflaterOutputStream, DigestOutputStream, InflaterOutputStream, PrintStream.

5.4. ObjectOutputStream

ObjectOutputStream פחית לכתוב סוגי נתונים וגרפים פרימיטיביים של אובייקטים של Java ליעד. אנחנו יכולים לבנות ObjectOutputStream באמצעות קיים OutputStream לכתוב ליעד ספציפי כמו קובץ.

שים לב כי יש צורך ליישם אובייקטים ניתן לבצע סדרתי ל ObjectOutputStream לכתוב אותם ליעד. תוכל למצוא פרטים נוספים על סידור Java כאן.

5.5. PipedOutputStream

א PipedOutputStream הוא שימושי ליצירת צינור תקשורת. PipedOutputStream יכול לכתוב נתונים אשר מחובר PipedInputStream יכול לקרוא.

PipedOutputStream כולל קונסטרוקטור לחבר אותו עם a PipedInputStream. לחלופין, אנו יכולים לעשות זאת מאוחר יותר באמצעות שיטה המפורטת ב PipedOutputStream שקוראים לו לְחַבֵּר().

6. OutputStream חציצה

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

יש לנו "זרמי נתונים" שנאגרו בג'אווה לטיפול בתרחישים אלה. BufferedOutputStreamכותב נתונים למאגר במקום אשר נשטף ליעד בתדירות נמוכה יותר, כאשר המאגר מתמלא, או השיטה סומק() נקרא.

BufferedOutputStream מרחיב FilterOutputStream דנו קודם ועוטף קיים OutputStream לכתוב ליעד:

חלל סטטי ציבורי buffedOutputStream (קובץ מחרוזת, מחרוזת ... נתונים) זורק IOException {try (BufferedOutputStream out = new BufferedOutputStream (FileOutputStream new (file))) {for (String s: data) {out.write (s.getBytes () ); out.write ("" .getBytes ()); }}}

הנקודה הקריטית שיש לציין היא שכל שיחה אל לִכתוֹב() עבור כל ארגומנט נתונים רק כותב למאגר ולא גורם לשיחה שעלולה להיות יקרה לקובץ.

במקרה שלעיל, אם אנו קוראים לשיטה זו עם נתונים כ- "שלום", "עולם!", הדבר יביא לכתיבת נתונים רק לקובץ כשהקוד ייצא מבלוק הניסיון-משאבים המכנה את השיטה. סגור() על BufferedOutputStream.

התוצאה היא קובץ פלט עם הטקסט הבא:

שלום עולם!

7. כתיבת טקסט עם OutputStreamWriter

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

בתים [] בתים = data.getBytes ();

Java מספקת שיעורים נוחים כדי לגשר על פער זה. למקרה של OutputStream, המעמד הזה הוא OutputStreamWriter. OutputStreamWriter עוטף OutputStream ויכול לכתוב ישירות תווים ליעד הרצוי.

אנו יכולים גם לספק את ה- OutputStreamWriter עם ערכת תווים לקידוד:

פלט חלל סטטי ציבוריStreamWriter (קובץ מחרוזת, נתוני מחרוזת) זורק IOException {נסה (OutputStream החוצה = FileOutputStream חדש (קובץ); סופר סופר = OutputStreamWriter חדש (out, "UTF-8")) {writer.write (data); }}

כעת, כפי שאנו רואים, איננו צריכים לבצע את השינוי של מערך התווים למערך הבייט לפני השימוש FileOutputStream.OutputStreamWriter עושה זאת בנוחות עבורנו.

באופן לא מפתיע כאשר אנו מכנים את השיטה הנ"ל עם נתונים כמו "שלום עולם!", הדבר נוצר לקובץ עם טקסט כ:

שלום עולם!

8. מסקנה

במאמר זה דנו בשיעור המופשט של Java OutputStream. עברנו על הממשקים שהוא מיישם ועל השיטות שהוא מספק.

ואז דנו בכמה מתתי הכיתות של OutputStream זמין ב- Java. סוף סוף דיברנו על חציצה וזרמי אופי.

כמו תמיד, הקוד לדוגמאות זמין ב- GitHub.