class IO

Eine Instanz der Klasse IO (üblicherweise als Stream bezeichnet) repräsentiert einen Ein-/Ausgabe-Stream im zugrunde liegenden Betriebssystem. Klasse IO ist die Grundlage für Eingabe und Ausgabe in Ruby.

Klasse File ist die einzige Klasse im Ruby-Kern, die eine Unterklasse von IO ist. Einige Klassen in der Ruby-Standardbibliothek sind ebenfalls Unterklassen von IO; dazu gehören TCPSocket und UDPSocket.

Die globale Konstante ARGF (auch zugänglich als $<) stellt einen IO-ähnlichen Stream bereit, der den Zugriff auf alle in ARGV gefundenen Dateipfade ermöglicht (oder auf STDIN, wenn ARGV leer ist). ARGF ist selbst keine Unterklasse von IO.

Klasse StringIO stellt einen IO-ähnlichen Stream bereit, der eine String handhabt. StringIO ist selbst keine Unterklasse von IO.

Wichtige Objekte, die auf IO basieren, sind

Eine Instanz von IO kann mit folgendem erstellt werden

Wie ein File-Stream hat ein IO-Stream

Und wie andere IO-Streams hat er

Erweiterung io/console

Die Erweiterung io/console bietet zahlreiche Methoden zur Interaktion mit der Konsole; das Einbinden fügt der Klasse IO zahlreiche Methoden hinzu.

Beispiel-Dateien

Viele Beispiele hier verwenden diese Variablen

# English text with newlines.
text = <<~EOT
  First line
  Second line

  Fourth line
  Fifth line
EOT

# Russian text.
russian = "\u{442 435 441 442}" # => "тест"

# Binary data.
data = "\u9990\u9991\u9992\u9993\u9994"

# Text file.
File.write('t.txt', text)

# File with Russian text.
File.write('t.rus', russian)

# File with binary data.
f = File.new('t.dat', 'wb:UTF-16')
f.write(data)
f.close

Öffnungsoptionen

Eine Reihe von IO-Methoden akzeptiert optionale Schlüsselwortargumente, die bestimmen, wie ein neuer Stream geöffnet werden soll

Ebenfalls verfügbar sind die Optionen von String#encode, die die Konvertierung zwischen externem und internem Encoding steuern können.

Grundlegende IO

Sie können grundlegende Stream-IO mit diesen Methoden durchführen, die typischerweise auf Multi-Byte-Strings operieren

Position

Ein IO-Stream hat eine nicht-negative ganzzahlige Position, die den Byte-Offset darstellt, an dem die nächste Lese- oder Schreiboperation stattfinden soll. Ein neuer Stream hat die Position Null (und Zeilennummer Null); die Methode rewind setzt die Position (und Zeilennummer) auf Null zurück.

Diese Methoden verwerfen Puffer und die dafür verwendeten Encoding::Converter-Instanzen.

Die relevanten Methoden

Geöffnete und geschlossene Streams

Ein neuer IO-Stream kann zum Lesen, zum Schreiben oder beides geöffnet sein.

Ein Stream wird automatisch geschlossen, wenn er vom Garbage Collector eingesammelt wird.

Der Versuch, auf einem geschlossenen Stream zu lesen oder zu schreiben, löst eine Ausnahme aus.

Die relevanten Methoden

Dateiende

Sie können abfragen, ob ein Stream an seinem Ende positioniert ist

Sie können zum Dateiende repositionieren, indem Sie die Methode IO#seek verwenden

f = File.new('t.txt')
f.eof? # => false
f.seek(0, :END)
f.eof? # => true
f.close

Oder indem Sie den gesamten Stream-Inhalt lesen (was langsamer ist als die Verwendung von IO#seek)

f.rewind
f.eof? # => false
f.read # => "First line\nSecond line\n\nFourth line\nFifth line\n"
f.eof? # => true

Zeilen-IO

Klasse IO unterstützt zeilenorientierte Eingabe und Ausgabe

Zeileneingabe

Klasse IO unterstützt zeilenorientierte Eingabe für Dateien und IO-Streams

Dateizeileneingabe

Sie können Zeilen aus einer Datei mit diesen Methoden lesen

Für jede dieser Methoden

Stream-Zeileneingabe

Sie können Zeilen aus einem IO-Stream mit diesen Methoden lesen

Für jede dieser Methoden

Zeilentrenner

Jede der Zeileneingabemethoden verwendet einen Zeilentrenner: die Zeichenkette, die bestimmt, was als Zeile gilt; sie wird manchmal als Input Record Separator bezeichnet.

Der Standard-Zeilentrenner wird aus der globalen Variablen $/ entnommen, deren Anfangswert "\n" ist.

Im Allgemeinen ist die nächste zu lesende Zeile alle Daten von der aktuellen Position bis zum nächsten Zeilentrenner (aber siehe Spezielle Zeilentrennerwerte).

f = File.new('t.txt')
# Method gets with no sep argument returns the next line, according to $/.
f.gets # => "First line\n"
f.gets # => "Second line\n"
f.gets # => "\n"
f.gets # => "Fourth line\n"
f.gets # => "Fifth line\n"
f.close

Sie können einen anderen Zeilentrenner verwenden, indem Sie das Argument sep übergeben

f = File.new('t.txt')
f.gets('l')   # => "First l"
f.gets('li')  # => "ine\nSecond li"
f.gets('lin') # => "ne\n\nFourth lin"
f.gets        # => "e\n"
f.close

Oder indem Sie die globale Variable $/ setzen

f = File.new('t.txt')
$/ = 'l'
f.gets # => "First l"
f.gets # => "ine\nSecond l"
f.gets # => "ine\n\nFourth l"
f.close
Spezielle Zeilentrennerwerte

Jede der Zeileneingabemethoden akzeptiert zwei spezielle Werte für den Parameter sep

Zeilenlimit

Jede der Zeileneingabemethoden verwendet ein ganzzahliges Zeilenlimit, das die Anzahl der zurückgegebenen Bytes begrenzt. (Ein Multi-Byte-Zeichen wird nicht aufgeteilt, und daher kann eine zurückgegebene Zeile etwas länger als das Limit sein).

Der Standardwert für das Limit ist -1; jeder negative Limitwert bedeutet, dass es kein Limit gibt.

Wenn kein Limit vorhanden ist, wird die Zeile nur durch sep bestimmt.

# Text with 1-byte characters.
File.open('t.txt') {|f| f.gets(1) }  # => "F"
File.open('t.txt') {|f| f.gets(2) }  # => "Fi"
File.open('t.txt') {|f| f.gets(3) }  # => "Fir"
File.open('t.txt') {|f| f.gets(4) }  # => "Firs"
# No more than one line.
File.open('t.txt') {|f| f.gets(10) } # => "First line"
File.open('t.txt') {|f| f.gets(11) } # => "First line\n"
File.open('t.txt') {|f| f.gets(12) } # => "First line\n"

# Text with 2-byte characters, which will not be split.
File.open('t.rus') {|f| f.gets(1).size } # => 1
File.open('t.rus') {|f| f.gets(2).size } # => 1
File.open('t.rus') {|f| f.gets(3).size } # => 2
File.open('t.rus') {|f| f.gets(4).size } # => 2
Zeilentrenner und Zeilenlimit

Mit den Argumenten sep und limit kombiniert dies die beiden Verhaltensweisen

Beispiel

File.open('t.txt') {|f| f.gets('li', 20) } # => "First li"
File.open('t.txt') {|f| f.gets('li', 2) }  # => "Fi"
Zeilennummer

Ein lesbarer IO-Stream hat eine nicht-negative ganzzahlige Zeilennummer

Sofern nicht durch einen Aufruf der Methode IO#lineno= geändert, ist die Zeilennummer die Anzahl der Zeilen, die von bestimmten zeilenorientierten Methoden gelesen wurden, gemäß dem effektiven Zeilentrenner

Ein neuer Stream hat zunächst die Zeilennummer Null (und Position Null); die Methode rewind setzt die Zeilennummer (und Position) auf Null zurück.

f = File.new('t.txt')
f.lineno # => 0
f.gets   # => "First line\n"
f.lineno # => 1
f.rewind
f.lineno # => 0
f.close

Das Lesen von Zeilen aus einem Stream ändert normalerweise seine Zeilennummer.

f = File.new('t.txt', 'r')
f.lineno   # => 0
f.readline # => "This is line one.\n"
f.lineno   # => 1
f.readline # => "This is the second line.\n"
f.lineno   # => 2
f.readline # => "Here's the third line.\n"
f.lineno   # => 3
f.eof?     # => true
f.close

Das Iterieren über Zeilen in einem Stream ändert normalerweise seine Zeilennummer.

File.open('t.txt') do |f|
  f.each_line do |line|
    p "position=#{f.pos} eof?=#{f.eof?} lineno=#{f.lineno}"
  end
end

Ausgabe

"position=11 eof?=false lineno=1"
"position=23 eof?=false lineno=2"
"position=24 eof?=false lineno=3"
"position=36 eof?=false lineno=4"
"position=47 eof?=true lineno=5"

Im Gegensatz zur Position des Streams beeinflusst die Zeilennummer nicht, wo die nächste Lese- oder Schreiboperation stattfindet.

f = File.new('t.txt')
f.lineno = 1000
f.lineno # => 1000
f.gets   # => "First line\n"
f.lineno # => 1001
f.close

Mit der Zeilennummer verbunden ist die globale Variable $.

Zeilenausgabe

Sie können zeilenweise in einen IO-Stream mit dieser Methode schreiben

Zeichen-IO

Sie können einen IO-Stream Zeichen für Zeichen mit diesen Methoden verarbeiten

Byte-IO

Sie können einen IO-Stream Byte für Byte mit diesen Methoden verarbeiten

Codepoint-IO

Sie können einen IO-Stream Codepoint für Codepoint verarbeiten

Was gibt es hier

Zuerst, was anderswo ist. Klasse IO

Hier bietet die Klasse IO Methoden, die nützlich sind für

Erstellen

Lesen

Schreiben

Positionieren

Iterieren

Einstellungen

Abfragen

Buffering

Low-Level-Zugriff

Sonstiges