C # โดยใช้สตรีม


116

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

หากฉันเข้าใจถูกต้องสตรีมมีสามประเภท:

  • stream
  • read stream
  • write stream

ถูกต้องหรือไม่ และตัวอย่างเช่นความแตกต่างระหว่าง a Memorystreamและ a FileStreamคืออะไร?


13
คุณอาจต้องการตรวจสอบstackoverflow.com/questions/507747/…
รีเซต

3
ใช้อาร์เรย์ของไบต์แล้วสร้าง wrapper สำหรับมัน ( Stream) ซึ่งแสดงวิธีการที่เป็นประโยชน์บางอย่างเช่นการอ่านการเขียนและการเปลี่ยนตำแหน่ง ตอนนี้คุณสามารถสร้างชั้นเรียนตามที่เก็บสำรองของพวกเขา (FileStream, MemoryStream) ซึ่งสืบทอดมาจากStreamและสร้างจากฟังก์ชันการทำงานนั้นตามที่เก็บสำรองโดยเฉพาะ
The Muffin Man

คำตอบ:


80

สตรีมเป็นวัตถุที่ใช้ในการถ่ายโอนข้อมูล มีคลาสสตรีมทั่วไปSystem.IO.Streamซึ่งได้มาจากคลาสสตรีมอื่น ๆ ทั้งหมดใน. NET Streamข้อเสนอชั้นเรียนกับไบต์

คลาสสตรีมคอนกรีตใช้เพื่อจัดการกับข้อมูลประเภทอื่นที่ไม่ใช่ไบต์ ตัวอย่างเช่น:

  • FileStreamระดับจะใช้เมื่อแหล่งภายนอกเป็นไฟล์
  • MemoryStream ใช้ในการจัดเก็บข้อมูลในหน่วยความจำ
  • System.Net.Sockets.NetworkStream จัดการข้อมูลเครือข่าย

สตรีมผู้อ่าน / นักเขียนเช่นStreamReaderและStreamWriterไม่ใช่สตรีม - ไม่ได้มาจากสตรีมได้รับการSystem.IO.Streamออกแบบมาเพื่อช่วยในการเขียนและอ่านข้อมูลจากและไปยังสตรีม!


3
ดังนั้นถ้าฉันเข้าใจถูกต้องสตรีมจะมีข้อมูลและไม่ได้ทำอะไรกับมัน คลาส 'ผู้ช่วยผู้อ่านและผู้เขียน' สามารถจัดการ (จัดการ) ข้อมูลภายในสตรีมได้หรือไม่?
Martijn

9
ไม่สตรีมไม่ใช่ที่เก็บข้อมูลซึ่งใช้ในการถ่ายโอนข้อมูลตัวอย่างเช่น FileStream ถ่ายโอนข้อมูลจากไบต์ [] ไปยังไฟล์ฟิซิคัล NetworkStream โอนไบต์ [] โดยซ็อกเก็ต คลาส Reader Writer เป็นคลาสตัวช่วยในการเขียนและอ่านจากสตรีมตัวอย่างเช่น StreamReader สามารถใช้เพื่ออ่านจาก Stream string not byte [] ถ้าคุณจะให้ FileStream เป็นพารามิเตอร์มันจะอ่านจากไฟล์ถ้า NetworkStream จากซ็อกเก็ต
Arsen Mkrtchyan

นอกจากนี้ StreamReader และ StreamWriter ยังใช้สำหรับการอ่านและเขียนสตรีม TEXT (อักขระ)
1c1cle

1
มีบทความดีๆที่จะช่วยให้คุณเข้าใจ MemoryStream codeproject.com/Articles/832387/…
Jiaji Li

2
@ user420667 คำถามที่ดี. ทั้งในกรณี AudioStream และ TemperatureStream พวกเขามักจะเป็น BinaryStreams ไปยังไดรเวอร์ที่เกี่ยวข้องกับอุปกรณ์ หรือคุณสามารถสร้าง CustomStream ที่สร้างขึ้นสำหรับอินเทอร์เฟซโดยเฉพาะ
1c1cle

62

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

คุณจะสังเกตเห็นว่าฟังก์ชันสำหรับการอ่านและการเขียนเป็นแบบไบต์ทั้งหมดเช่น WriteByte () ไม่มีฟังก์ชันสำหรับจัดการกับจำนวนเต็มสตริงและอื่น ๆ สิ่งนี้ทำให้สตรีมมีจุดประสงค์ทั่วไปมาก แต่ใช้งานง่ายน้อยกว่าในกรณีที่คุณต้องการถ่ายโอนข้อความ

อย่างไรก็ตาม. NET มีคลาสที่แปลงระหว่างประเภทเนทีฟและอินเทอร์เฟซสตรีมระดับต่ำและโอนข้อมูลไปยังหรือจากสตรีมให้คุณ คลาสที่โดดเด่นบางอย่าง ได้แก่ :

StreamWriter // Badly named. Should be TextWriter.
StreamReader // Badly named. Should be TextReader.
BinaryWriter
BinaryReader

ในการใช้สิ่งเหล่านี้อันดับแรกคุณได้รับสตรีมของคุณจากนั้นสร้างหนึ่งในคลาสข้างต้นและเชื่อมโยงกับสตรีม เช่น

MemoryStream memoryStream = new MemoryStream();
StreamWriter myStreamWriter = new StreamWriter(memoryStream);

StreamReader และ StreamWriter แปลงระหว่างชนิดเนทีฟและการแสดงสตริงจากนั้นโอนสายไปยังและจากสตรีมเป็นไบต์ ดังนั้น

myStreamWriter.Write(123);

จะเขียน "123" (สามตัวอักษร '1', '2' ตามด้วย '3') ลงในสตรีม หากคุณกำลังจัดการกับไฟล์ข้อความ (เช่น html) StreamReader และ StreamWriter คือคลาสที่คุณจะใช้

แต่ทว่า

myBinaryWriter.Write(123);

จะเขียนสี่ไบต์แทนค่าจำนวนเต็ม 32 บิต 123 (0x7B, 0x00, 0x00, 0x00) หากคุณกำลังจัดการกับไฟล์ไบนารีหรือโปรโตคอลเครือข่าย BinaryReader และ BinaryWriter คือสิ่งที่คุณอาจใช้ (หากคุณกำลังแลกเปลี่ยนข้อมูลกับเครือข่ายหรือระบบอื่น ๆ ที่คุณต้องมีสติในการendiannessแต่ที่โพสต์อื่น.)


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

นอกจากนี้แม้แต่คลาสนักเขียนและผู้อ่านไบนารีก็มีชื่อไม่ดี
Tarik

22

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


1
ชอบที่จะเห็นตัวอย่างของสิ่งที่คุณเพิ่งพูดว่า "ทำงานกับชิ้นส่วนเล็ก ๆ ของมัน"
Jenna Leaf

2
สตรีมยังดีสำหรับข้อมูลจำนวนน้อยด้วย หากโปรแกรมเมอร์ C # ต้องการจัดการเนื้อหาของไฟล์เขา / เขาต้องใช้สตรีมโดยไม่คำนึงถึงจำนวนข้อมูล คำสั่งเดียวกันนี้เป็นจริงสำหรับสตรีมเครือข่ายเช่นกัน จริงอยู่ถ้าโปรแกรมเมอร์เขียนโค้ดเป็นภาษาระดับล่างเช่น C ก็เป็นไปได้ที่จะเขียนตัวอักษรหรือไบต์ลงในดิสก์หรือซ็อกเก็ตโดยตรง แต่ถึงแม้จะมีข้อมูลเพียงเล็กน้อย แต่ก็ใช้เวลานานและมีแนวโน้มที่จะ ความผิดพลาด
1c1cle

10

สตรีมเป็นเพียงสิ่งที่เป็นนามธรรม (หรือกระดาษห่อหุ้ม) บนphysicalสตรีมไบต์ นี้กระแสที่เรียกว่าphysical base streamดังนั้นจึงมีอยู่เสมอกระแสฐานมากกว่าที่เสื้อคลุมสตรีมจะถูกสร้างขึ้นและทำให้เสื้อคลุมนั้นตั้งตามชื่อประเภทกระแสฐานเช่นFileStream, MemoryStreamฯลฯ

ข้อดีของ Stream Wrapper คือคุณจะได้รับ API แบบรวมเพื่อโต้ตอบกับสตรีมทุกประเภทusb, fileเป็นต้น

เหตุใดคุณจึงถือว่าข้อมูลเป็นสตรีม - เนื่องจากชิ้นข้อมูลถูกโหลดตามความต้องการเราจึงสามารถตรวจสอบ / ประมวลผลข้อมูลเป็นกลุ่มแทนที่จะโหลดข้อมูลทั้งหมดลงในหน่วยความจำ นี่คือวิธีที่โปรแกรมส่วนใหญ่จัดการกับไฟล์ขนาดใหญ่เช่นการเข้ารหัสไฟล์อิมเมจ OS


4

มีเพียงประเภทพื้นฐานStreamเท่านั้น อย่างไรก็ตามในหลาย ๆ กรณีสมาชิกบางคนจะโยนข้อยกเว้นเมื่อถูกเรียกเนื่องจากในบริบทนั้นการดำเนินการไม่พร้อมใช้งาน

ตัวอย่างเช่น a MemoryStreamเป็นเพียงวิธีการย้ายไบต์เข้าและออกจากหน่วยความจำ ดังนั้นคุณสามารถเรียกอ่านและเขียนได้

ในทางกลับกันFileStreamอนุญาตให้คุณอ่านหรือเขียน (หรือทั้งสองอย่าง) จาก / ไปยังไฟล์ คุณสามารถอ่านหรือเขียนได้จริงหรือไม่นั้นขึ้นอยู่กับวิธีการเปิดไฟล์ คุณไม่สามารถเขียนลงในไฟล์ได้หากคุณเปิดไว้สำหรับการเข้าถึงแบบอ่านเท่านั้น


3

ฉันจะเริ่มต้นด้วยการอ่านสตรีมบน MSDN: http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

Memorystream และ FileStream เป็นสตรีมที่ใช้ในการทำงานกับหน่วยความจำดิบและไฟล์ตามลำดับ ...


ขอบคุณสำหรับลิงค์ ฉันชอบที่ "คุณสามารถเรียกดูซอร์สโค้ดออนไลน์ดาวน์โหลดข้อมูลอ้างอิงสำหรับการดูแบบออฟไลน์และทำตามขั้นตอนต่างๆ (รวมถึงแพตช์และการอัปเดต) ในระหว่างการดีบัก" ฟีเจอร์นี้นำเสนอข้อมูลเชิงลึกระดับใหม่
David

1

ฉันจะไม่เรียกสตรีมประเภทต่างๆเหล่านั้น คลาส Stream มีคุณสมบัติ CanRead และ CanWrite ที่บอกคุณว่าสามารถอ่านและเขียนสตรีมโดยเฉพาะได้หรือไม่

ความแตกต่างที่สำคัญระหว่างคลาสสตรีมที่แตกต่างกัน (เช่น MemoryStream vs FileStream) คือที่เก็บข้อมูลสำรองซึ่งข้อมูลจะถูกอ่านจากที่ใดหรือถูกเขียนถึงที่ไหน มันชัดเจนจากชื่อ MemoryStream เก็บข้อมูลไว้ในหน่วยความจำเท่านั้น FileStream ได้รับการสนับสนุนโดยไฟล์บนดิสก์ NetworkStream อ่านข้อมูลจากเครือข่ายและอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.