class StringIO
Die Klasse StringIO unterstützt den Zugriff auf einen String als Stream, in mancher Hinsicht ähnlich der Klasse IO.
Sie können eine StringIO-Instanz mit
-
StringIO.newerstellen: gibt ein neues StringIO-Objekt zurück, das den angegebenen String enthält. -
StringIO.open: übergibt ein neues StringIO-Objekt an den angegebenen Block.
Wie ein IO-Stream hat ein StringIO-Stream bestimmte Eigenschaften
-
Lese-/Schreibmodus: ob der Stream gelesen, geschrieben, angehängt usw. werden kann; siehe Lese-/Schreibmodus.
-
Datenmodus: nur Text oder Binär; siehe Datenmodus.
-
Kodierungen: interne und externe Kodierungen; siehe Kodierungen.
-
Position: wo im Stream der nächste Lese- oder Schreibvorgang stattfinden soll; siehe Position.
-
Zeilennummer: eine spezielle, zeilenorientierte „Position“ (unterschiedlich von der oben genannten Position); siehe Zeilennummer.
-
Geöffnet/Geschlossen: ob der Stream zum Lesen oder Schreiben geöffnet oder geschlossen ist. siehe Geöffnete/Geschlossene Streams.
-
BOM: Byte Order Mark; siehe Byte Order Mark.
Über die Beispiele
Die Beispiele auf dieser Seite gehen davon aus, dass StringIO bereits eingebunden wurde
require 'stringio'
Und dass diese Konstante definiert wurde
TEXT = <<EOT First line Second line Fourth line Fifth line EOT
Stream-Eigenschaften
Lese-/Schreibmodus
Zusammenfassung
| Modus | Anfangs gelöscht? | Lesen | Schreiben |
|---|---|---|---|
'r': schreibgeschützt |
Nein | Überall | Error |
'w': schreibgeschützt |
Ja | Error | Überall |
'a': nur anhängen |
Nein | Error | Nur am Ende |
'r+': lesen/schreiben |
Nein | Überall | Überall |
'w+': lesen/schreiben |
Ja | Überall | Überall |
'a+': lesen/anhängen |
Nein | Überall | Nur am Ende |
Jeder Abschnitt unten beschreibt einen Lese-/Schreibmodus.
Jeder der Modi kann als String oder als Dateikonstante angegeben werden; Beispiel
strio = StringIO.new('foo', 'a') strio = StringIO.new('foo', File::WRONLY | File::APPEND)
'r': Nur Lesen
Modus angegeben als einer von
-
String:
'r'. -
Konstante:
File::RDONLY.
Anfangszustand
strio = StringIO.new('foobarbaz', 'r') strio.pos # => 0 # Beginning-of-stream. strio.string # => "foobarbaz" # Not cleared.
Kann überall gelesen werden
strio.gets(3) # => "foo" strio.gets(3) # => "bar" strio.pos = 9 strio.gets(3) # => nil
Kann nicht geschrieben werden
strio.write('foo') # Raises IOError: not opened for writing
'w': Nur Schreiben
Modus angegeben als einer von
-
String:
'w'. -
Konstante:
File::WRONLY.
Anfangszustand
strio = StringIO.new('foo', 'w') strio.pos # => 0 # Beginning of stream. strio.string # => "" # Initially cleared.
Kann überall geschrieben werden (auch über das Ende des Streams hinaus)
strio.write('foobar') strio.string # => "foobar" strio.rewind strio.write('FOO') strio.string # => "FOObar" strio.pos = 3 strio.write('BAR') strio.string # => "FOOBAR" strio.pos = 9 strio.write('baz') strio.string # => "FOOBAR\u0000\u0000\u0000baz" # Null-padded.
Kann nicht gelesen werden
strio.read # Raises IOError: not opened for reading
'a': Nur Anhängen
Modus angegeben als einer von
-
String:
'a'. -
Konstante:
File::WRONLY | File::APPEND.
Anfangszustand
strio = StringIO.new('foo', 'a') strio.pos # => 0 # Beginning-of-stream. strio.string # => "foo" # Not cleared.
Kann nur am Ende geschrieben werden; die Position beeinflusst das Schreiben nicht
strio.write('bar') strio.string # => "foobar" strio.write('baz') strio.string # => "foobarbaz" strio.pos = 400 strio.write('bat') strio.string # => "foobarbazbat"
Kann nicht gelesen werden
strio.gets # Raises IOError: not opened for reading
'r+': Lesen/Schreiben
Modus angegeben als einer von
-
String:
'r+'. -
Konstante:
File::RDRW.
Anfangszustand
strio = StringIO.new('foobar', 'r+') strio.pos # => 0 # Beginning-of-stream. strio.string # => "foobar" # Not cleared.
Kann überall geschrieben werden (auch über das Ende des Streams hinaus)
strio.write('FOO') strio.string # => "FOObar" strio.write('BAR') strio.string # => "FOOBAR" strio.write('BAZ') strio.string # => "FOOBARBAZ" strio.pos = 12 strio.write('BAT') strio.string # => "FOOBARBAZ\u0000\u0000\u0000BAT" # Null padded.
Kann überall gelesen werden
strio.pos = 0 strio.gets(3) # => "FOO" strio.pos = 6 strio.gets(3) # => "BAZ" strio.pos = 400 strio.gets(3) # => nil
'w+': Lesen/Schreiben (Anfangs gelöscht)
Modus angegeben als einer von
-
String:
'w+'. -
Konstante:
File::RDWR | File::TRUNC.
Anfangszustand
strio = StringIO.new('foo', 'w+') strio.pos # => 0 # Beginning-of-stream. strio.string # => "" # Truncated.
Kann überall geschrieben werden (auch über das Ende des Streams hinaus)
strio.write('foobar') strio.string # => "foobar" strio.rewind strio.write('FOO') strio.string # => "FOObar" strio.write('BAR') strio.string # => "FOOBAR" strio.write('BAZ') strio.string # => "FOOBARBAZ" strio.pos = 12 strio.write('BAT') strio.string # => "FOOBARBAZ\u0000\u0000\u0000BAT" # Null-padded.
Kann überall gelesen werden
strio.rewind strio.gets(3) # => "FOO" strio.gets(3) # => "BAR" strio.pos = 12 strio.gets(3) # => "BAT" strio.pos = 400 strio.gets(3) # => nil
'a+': Lesen/Anhängen
Modus angegeben als einer von
-
String:
'a+'. -
Konstante:
File::RDWR | File::APPEND.
Anfangszustand
strio = StringIO.new('foo', 'a+') strio.pos # => 0 # Beginning-of-stream. strio.string # => "foo" # Not cleared.
Kann nur am Ende geschrieben werden; rewind; die Position beeinflusst das Schreiben nicht
strio.write('bar') strio.string # => "foobar" strio.write('baz') strio.string # => "foobarbaz" strio.pos = 400 strio.write('bat') strio.string # => "foobarbazbat"
Kann überall gelesen werden
strio.rewind strio.gets(3) # => "foo" strio.gets(3) # => "bar" strio.pos = 9 strio.gets(3) # => "bat" strio.pos = 400 strio.gets(3) # => nil
Data Modus
Um anzugeben, ob der Stream als Text oder als Binärdaten behandelt werden soll, kann einer der folgenden Suffixe an jeden der obigen String-Lese-/Schreibmodi angehängt werden
-
't': Text; initialisiert die Kodierung als Encoding::UTF_8. -
'b': Binär; initialisiert die Kodierung als Encoding::ASCII_8BIT.
Wenn keiner angegeben ist, ist der Stream standardmäßig Textdaten.
Beispiele
strio = StringIO.new('foo', 'rt') strio.external_encoding # => #<Encoding:UTF-8> data = "\u9990\u9991\u9992\u9993\u9994" strio = StringIO.new(data, 'rb') strio.external_encoding # => #<Encoding:BINARY (ASCII-8BIT)>
Wenn der Datenmodus angegeben ist, darf der Lese-/Schreibmodus nicht weggelassen werden
StringIO.new(data, 'b') # Raises ArgumentError: invalid access mode b
Ein Text-Stream kann durch Aufrufen der Instanzmethode binmode in einen Binär-Stream geändert werden; ein Binär-Stream kann nicht in einen Text-Stream geändert werden.
Kodierungen
Ein Stream hat eine Kodierung; siehe Kodierungen.
Die anfängliche Kodierung für einen neuen oder wiedereröffneten Stream hängt von seinem Datenmodus ab
-
Text:
Encoding::UTF_8. -
Binär:
Encoding::ASCII_8BIT.
Diese Instanzmethoden sind relevant
-
external_encoding: gibt die aktuelle Kodierung des Streams alsEncoding-Objekt zurück. -
internal_encoding: gibtnilzurück; ein Stream hat keine interne Kodierung. -
set_encoding: setzt die Kodierung für den Stream. -
set_encoding_by_bom: setzt die Kodierung für den Stream auf die BOM (Byte Order Mark) des Streams.
Beispiele
strio = StringIO.new('foo', 'rt') # Text mode. strio.external_encoding # => #<Encoding:UTF-8> data = "\u9990\u9991\u9992\u9993\u9994" strio = StringIO.new(data, 'rb') # Binary mode. strio.external_encoding # => #<Encoding:BINARY (ASCII-8BIT)> strio = StringIO.new('foo') strio.external_encoding # => #<Encoding:UTF-8> strio.set_encoding('US-ASCII') strio.external_encoding # => #<Encoding:US-ASCII>
Position
Ein Stream hat eine Position, einen Integer-Offset (in Bytes) im Stream. Die anfängliche Position eines Streams ist Null.
Abrufen und Setzen der Position
Jede dieser Methoden initialisiert (auf Null) die Position eines neuen oder wiedereröffneten Streams
-
::new: gibt einen neuen Stream zurück. -
::open: übergibt einen neuen Stream an den Block. -
reopen: initialisiert den Stream neu.
Jede dieser Methoden fragt ab, ruft ab oder setzt die Position, ohne den Stream anderweitig zu ändern
-
eof?: gibt zurück, ob die Position am Ende des Streams ist. -
pos: gibt die Position zurück. -
pos=: setzt die Position. -
rewind: setzt die Position auf Null. -
seek: setzt die Position.
Beispiele
strio = StringIO.new('foobar') strio.pos # => 0 strio.pos = 3 strio.pos # => 3 strio.eof? # => false strio.rewind strio.pos # => 0 strio.seek(0, IO::SEEK_END) strio.pos # => 6 strio.eof? # => true
Position vor und nach dem Lesen
Mit Ausnahme von pread beginnt eine Stream-Lesemethode (siehe Grundlegendes Lesen) mit dem Lesen an der aktuellen Position.
Mit Ausnahme von pread verschiebt eine Lesemethode die Position über den gelesenen Teilstring.
Beispiele
strio = StringIO.new(TEXT) strio.string # => "First line\nSecond line\n\nFourth line\nFifth line\n" strio.pos # => 0 strio.getc # => "F" strio.pos # => 1 strio.gets # => "irst line\n" strio.pos # => 11 strio.pos = 24 strio.gets # => "Fourth line\n" strio.pos # => 36 strio = StringIO.new('тест') # Four 2-byte characters. strio.pos = 0 # At first byte of first character. strio.read # => "тест" strio.pos = 1 # At second byte of first character. strio.read # => "\x82ест" strio.pos = 2 # At first of second character. strio.read # => "ест" strio = StringIO.new(TEXT) strio.pos = 15 a = [] strio.each_line {|line| a.push(line) } a # => ["nd line\n", "\n", "Fourth line\n", "Fifth line\n"] strio.pos # => 47 ## End-of-stream.
Position vor und nach dem Schreiben
Jede dieser Methoden beginnt mit dem Schreiben an der aktuellen Position und verschiebt die Position bis zum Ende des geschriebenen Teilstrings
-
putc: schreibt das gegebene Zeichen. -
write: schreibt die gegebenen Objekte als Strings. -
Kernel#puts: schreibt gegebene Objekte als Strings, gefolgt von einem Zeilenumbruch.
Beispiele
strio = StringIO.new('foo') strio.pos # => 0 strio.putc('b') strio.string # => "boo" strio.pos # => 1 strio.write('r') strio.string # => "bro" strio.pos # => 2 strio.puts('ew') strio.string # => "brew\n" strio.pos # => 5 strio.pos = 8 strio.write('foo') strio.string # => "brew\n\u0000\u0000\u0000foo" strio.pos # => 11
Jede dieser Methoden schreibt *vor* die aktuelle Position und dekrementiert die Position, sodass die geschriebenen Daten als nächstes gelesen werden können
Beispiele
strio = StringIO.new('foo') strio.pos = 2 strio.ungetc('x') strio.pos # => 1 strio.string # => "fxo" strio.ungetc('x') strio.pos # => 0 strio.string # => "xxo"
Diese Methode hat keinen Einfluss auf die Position
-
truncate: kürzt den String des Streams auf die angegebene Größe.
Beispiele
strio = StringIO.new('foobar') strio.pos # => 0 strio.truncate(3) strio.string # => "foo" strio.pos # => 0 strio.pos = 500 strio.truncate(0) strio.string # => "" strio.pos # => 500
Zeilennummer
Ein Stream hat eine Zeilennummer, die anfangs Null ist
Die Zeilennummer kann durch Lesen beeinflusst werden (aber niemals durch Schreiben); im Allgemeinen wird die Zeilennummer jedes Mal erhöht, wenn der Aufzeichnungstrennzeichen (Standard: "\n") gelesen wird.
Beispiele
strio = StringIO.new(TEXT) strio.string # => "First line\nSecond line\n\nFourth line\nFifth line\n" strio.lineno # => 0 strio.gets # => "First line\n" strio.lineno # => 1 strio.getc # => "S" strio.lineno # => 1 strio.gets # => "econd line\n" strio.lineno # => 2 strio.gets # => "\n" strio.lineno # => 3 strio.gets # => "Fourth line\n" strio.lineno # => 4
Das Setzen der Position beeinflusst die Zeilennummer nicht
strio.pos = 0 strio.lineno # => 4 strio.gets # => "First line\n" strio.pos # => 11 strio.lineno # => 5
Und das Setzen der Zeilennummer beeinflusst die Position nicht
strio.lineno = 10 strio.pos # => 11 strio.gets # => "Second line\n" strio.lineno # => 11 strio.pos # => 23
Geöffnete/Geschlossene Streams
Ein neuer Stream ist zum Lesen oder Schreiben geöffnet und kann für beides geöffnet sein; siehe Lese-/Schreibmodus.
Jede dieser Methoden initialisiert den Lese-/Schreibmodus für einen neuen oder wiedereröffneten Stream
-
::new: gibt einen neuen Stream zurück. -
::open: übergibt einen neuen Stream an den Block. -
reopen: initialisiert den Stream neu.
Andere relevante Methoden
-
close: schließt den Stream für Lesen und Schreiben. -
close_read: schließt den Stream für das Lesen. -
close_write: schließt den Stream für das Schreiben. -
closed?: gibt zurück, ob der Stream für Lesen und Schreiben geschlossen ist. -
closed_read?: gibt zurück, ob der Stream für das Lesen geschlossen ist. -
closed_write?: gibt zurück, ob der Stream für das Schreiben geschlossen ist.
BOM (Byte Order Mark)
Der String, der für ::new, ::open oder reopen bereitgestellt wird, kann ein optionales BOM (Byte Order Mark) am Anfang des Strings enthalten; das BOM kann die Kodierung des Streams beeinflussen.
Das BOM (falls vorhanden)
-
Wird als Teil des Strings des Streams gespeichert.
-
Beeinflusst die Kodierung nicht sofort.
-
Wird *anfänglich* als Teil des Streams betrachtet.
utf8_bom = "\xEF\xBB\xBF" string = utf8_bom + 'foo' string.bytes # => [239, 187, 191, 102, 111, 111] strio.string.bytes.take(3) # => [239, 187, 191] # The BOM. strio = StringIO.new(string, 'rb') strio.string.bytes # => [239, 187, 191, 102, 111, 111] # BOM is part of the stored string. strio.external_encoding # => #<Encoding:BINARY (ASCII-8BIT)> # Default for a binary stream. strio.gets # => "\xEF\xBB\xBFfoo" # BOM is part of the stream.
Sie können die Instanzmethode set_encoding_by_bom aufrufen, um das gespeicherte BOM zu „aktivieren“; danach das BOM
-
Wird immer noch als Teil des Strings des Streams gespeichert.
-
Bestimmt (und hat möglicherweise geändert) die Kodierung des Streams.
-
Wird *nicht mehr* als Teil des Streams betrachtet.
strio.set_encoding_by_bom strio.string.bytes # => [239, 187, 191, 102, 111, 111] # BOM is still part of the stored string. strio.external_encoding # => #<Encoding:UTF-8> # The new encoding. strio.rewind # => 0 strio.gets # => "foo" # BOM is not part of the stream.
Grundlegende Stream-IO
Grundlegendes Lesen
Sie können aus dem Stream mit diesen Instanzmethoden lesen
-
getbyte: liest und gibt das nächste Byte zurück. -
getc: liest und gibt das nächste Zeichen zurück. -
gets: liest und gibt die gesamte oder einen Teil der nächsten Zeile zurück. -
read: liest und gibt die gesamten oder einen Teil der verbleibenden Daten im Stream zurück. -
readlines: liest die verbleibenden Daten des Streams und gibt ein Array seiner Zeilen zurück. -
Kernel#readline: wie
gets, aber löst eine Ausnahme aus, wenn das Ende des Streams erreicht ist.
Sie können den Stream mit diesen Instanzmethoden durchlaufen
-
each_byte: liest jedes verbleibende Byte und übergibt es an den Block. -
each_char: liest jedes verbleibende Zeichen und übergibt es an den Block. -
each_codepoint: liest jeden verbleibenden Codepunkt und übergibt ihn an den Block. -
each_line: liest die gesamte oder einen Teil jeder verbleibenden Zeile und übergibt den gelesenen String an den Block
Diese Instanzmethode ist in einer Multi-Threaded-Anwendung nützlich
-
pread: liest und gibt den gesamten oder einen Teil des Streams zurück.
Grundlegendes Schreiben
Sie können in den Stream schreiben und dabei die Position verschieben, mit diesen Instanzmethoden
-
putc: schreibt ein gegebenes Zeichen. -
write: schreibt die gegebenen Objekte als Strings. -
Kernel#puts schreibt gegebene Objekte als Strings, jeweils gefolgt von einem Zeilenumbruch.
Sie können in den Stream „zurückschieben“ mit diesen Instanzmethoden; jede schreibt *vor* die aktuelle Position und dekrementiert die Position, sodass die geschriebenen Daten als nächstes gelesen werden.
Eine weitere Schreibmethode
-
truncate: kürzt den String des Streams auf die angegebene Größe.
Zeilen-IO
Lesen
-
gets: liest und gibt die nächste Zeile zurück. -
Kernel#readline: wie
gets, aber löst eine Ausnahme aus, wenn das Ende des Streams erreicht ist. -
readlines: liest die verbleibenden Daten des Streams und gibt ein Array seiner Zeilen zurück. -
each_line: liest jede verbleibende Zeile und übergibt sie an den Block
Schreiben
-
Kernel#puts: schreibt gegebene Objekte, jeweils gefolgt von einem Zeilenumbruch.
Zeichen-IO
Lesen
-
each_char: liest jedes verbleibende Zeichen und übergibt es an den Block. -
getc: liest und gibt das nächste Zeichen zurück.
Schreiben
Byte-IO
Lesen
-
each_byte: liest jedes verbleibende Byte und übergibt es an den Block. -
getbyte: liest und gibt das nächste Byte zurück.
Schreiben
-
ungetbyte: schiebt das gegebene Byte zurück.
Codepunkt-IO
Lesen
-
each_codepoint: liest jeden verbleibenden Codepunkt und übergibt ihn an den Block.
Constants
- MAX_LENGTH
-
Maximale Länge, die eine
StringIO-Instanz enthalten kann - VERSION
-
Die Versionszeichenfolge
Öffentliche Klassenmethoden
Source
static VALUE
strio_initialize(int argc, VALUE *argv, VALUE self)
{
struct StringIO *ptr = check_strio(self);
if (!ptr) {
DATA_PTR(self) = ptr = strio_alloc();
}
rb_call_super(0, 0);
return strio_init(argc, argv, ptr, self);
}
Gibt eine neue StringIO-Instanz zurück, die aus string und mode gebildet wird; die Instanz sollte geschlossen werden, wenn sie nicht mehr benötigt wird
strio = StringIO.new strio.string # => "" strio.closed_read? # => false strio.closed_write? # => false strio.close
Wenn string eingefroren ist, ist der Standardmodus 'r'
strio = StringIO.new('foo'.freeze) strio.string # => "foo" strio.closed_read? # => false strio.closed_write? # => true strio.close
Das Argument mode muss ein gültiger Zugriffsmodus sein, der ein String oder eine Integer-Konstante sein kann
StringIO.new('foo', 'w+') StringIO.new('foo', File::RDONLY)
Verwandt: StringIO.open (übergibt das StringIO-Objekt an den Block; schließt das Objekt nach dem Verlassen des Blocks automatisch).
Source
static VALUE
strio_s_open(int argc, VALUE *argv, VALUE klass)
{
VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
if (!rb_block_given_p()) return obj;
return rb_ensure(rb_yield, obj, strio_finalize, obj);
}
Erstellt eine neue StringIO-Instanz durch Aufrufen von StringIO.new(string, mode).
Wenn kein Block übergeben wird, wird die neue Instanz zurückgegeben
strio = StringIO.open # => #<StringIO>
Wenn ein Block übergeben wird, wird der Block mit der neuen Instanz aufgerufen und der Rückgabewert des Blocks zurückgegeben; die Instanz wird beim Verlassen des Blocks geschlossen
StringIO.open('foo') {|strio| strio.string.upcase } # => "FOO"
Verwandt: StringIO.new.
Öffentliche Instanzmethoden
Source
static VALUE
strio_binmode(VALUE self)
{
struct StringIO *ptr = StringIO(self);
rb_encoding *enc = rb_ascii8bit_encoding();
ptr->enc = enc;
if (WRITABLE(self)) {
rb_enc_associate(ptr->string, enc);
}
return self;
}
Setzt den Datenmodus in self auf Binärmodus; siehe Datenmodus.
Source
static VALUE
strio_close(VALUE self)
{
StringIO(self);
RBASIC(self)->flags &= ~STRIO_READWRITE;
return Qnil;
}
Schließt self für Lesen und Schreiben; gibt nil zurück
strio = StringIO.new strio.closed? # => false strio.close # => nil strio.closed? # => true strio.read # Raises IOError: not opened for reading strio.write # Raises IOError: not opened for writing
Verwandt: StringIO#close_read, StringIO#close_write, StringIO.closed?.
Source
static VALUE
strio_close_read(VALUE self)
{
struct StringIO *ptr = StringIO(self);
if (!(ptr->flags & FMODE_READABLE)) {
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
}
RBASIC(self)->flags &= ~STRIO_READABLE;
return Qnil;
}
Schließt self für das Lesen; die Einstellung für das Schreiben bleibt unverändert; gibt nil zurück
strio = StringIO.new strio.closed_read? # => false strio.close_read # => nil strio.closed_read? # => true strio.closed_write? # => false strio.read # Raises IOError: not opened for reading
Verwandt: StringIO#close, StringIO#close_write.
Source
static VALUE
strio_close_write(VALUE self)
{
struct StringIO *ptr = StringIO(self);
if (!(ptr->flags & FMODE_WRITABLE)) {
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
}
RBASIC(self)->flags &= ~STRIO_WRITABLE;
return Qnil;
}
Schließt self für das Schreiben; die Einstellung für das Lesen bleibt unverändert; gibt nil zurück
strio = StringIO.new strio.closed_write? # => false strio.close_write # => nil strio.closed_write? # => true strio.closed_read? # => false strio.write('foo') # Raises IOError: not opened for writing
Verwandt: StringIO#close, StringIO#close_read, StringIO#closed_write?.
Source
static VALUE
strio_closed(VALUE self)
{
StringIO(self);
if (!CLOSED(self)) return Qfalse;
return Qtrue;
}
Gibt zurück, ob self für Lesen und Schreiben geschlossen ist
strio = StringIO.new strio.closed? # => false # Open for reading and writing. strio.close_read strio.closed? # => false # Still open for writing. strio.close_write strio.closed? # => true # Now closed for both.
Verwandt: StringIO.closed_read?, StringIO.closed_write?.
Source
static VALUE
strio_closed_read(VALUE self)
{
StringIO(self);
if (READABLE(self)) return Qfalse;
return Qtrue;
}
Gibt zurück, ob self für das Lesen geschlossen ist
strio = StringIO.new strio.closed_read? # => false strio.close_read strio.closed_read? # => true
Verwandt: StringIO#closed?, StringIO#closed_write?, StringIO#close_read.
Source
static VALUE
strio_closed_write(VALUE self)
{
StringIO(self);
if (WRITABLE(self)) return Qfalse;
return Qtrue;
}
Gibt zurück, ob self für das Schreiben geschlossen ist
strio = StringIO.new strio.closed_write? # => false strio.close_write strio.closed_write? # => true
Verwandt: StringIO#close_write, StringIO#closed?, StringIO#closed_read?.
Source
static VALUE
strio_each(int argc, VALUE *argv, VALUE self)
{
VALUE line;
struct StringIO *ptr = readable(self);
struct getline_arg arg;
RETURN_ENUMERATOR(self, argc, argv);
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
}
while (!NIL_P(line = strio_getline(&arg, ptr))) {
rb_yield(line);
}
return self;
}
Source
static VALUE
strio_each_byte(VALUE self)
{
struct StringIO *ptr;
RETURN_ENUMERATOR(self, 0, 0);
while ((ptr = strio_to_read(self)) != NULL) {
char c = RSTRING_PTR(ptr->string)[ptr->pos++];
rb_yield(CHR2FIX(c));
}
return self;
}
Mit übergebenem Block, ruft den Block mit jedem verbleibenden Byte im Stream auf; positioniert den Stream am Dateiende; gibt self zurück
bytes = [] strio = StringIO.new('hello') # Five 1-byte characters. strio.each_byte {|byte| bytes.push(byte) } strio.eof? # => true bytes # => [104, 101, 108, 108, 111] bytes = [] strio = StringIO.new('тест') # Four 2-byte characters. strio.each_byte {|byte| bytes.push(byte) } bytes # => [209, 130, 208, 181, 209, 129, 209, 130] bytes = [] strio = StringIO.new('こんにちは') # Five 3-byte characters. strio.each_byte {|byte| bytes.push(byte) } bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
Die Position im Stream spielt eine Rolle
bytes = [] strio = StringIO.new('こんにちは') strio.getc # => "こ" strio.pos # => 3 # 3-byte character was read. strio.each_byte {|byte| bytes.push(byte) } bytes # => [227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
Wenn am Dateiende, wird der Block nicht aufgerufen
strio.eof? # => true strio.each_byte {|byte| fail 'Boo!' } strio.eof? # => true
Ohne Block wird ein neuer Enumerator zurückgegeben.
Verwandt: StringIO#each_char, StringIO#each_codepoint, StringIO#each_line.
Source
static VALUE
strio_each_char(VALUE self)
{
VALUE c;
RETURN_ENUMERATOR(self, 0, 0);
while (!NIL_P(c = strio_getc(self))) {
rb_yield(c);
}
return self;
}
Mit übergebenem Block, ruft den Block mit jedem verbleibenden Zeichen im Stream auf; positioniert den Stream am Dateiende; gibt self zurück
chars = [] strio = StringIO.new('hello') strio.each_char {|char| chars.push(char) } strio.eof? # => true chars # => ["h", "e", "l", "l", "o"] chars = [] strio = StringIO.new('тест') strio.each_char {|char| chars.push(char) } chars # => ["т", "е", "с", "т"] chars = [] strio = StringIO.new('こんにちは') strio.each_char {|char| chars.push(char) } chars # => ["こ", "ん", "に", "ち", "は"]
Die Stream-Position spielt eine Rolle
chars = [] strio = StringIO.new('こんにちは') strio.getc # => "こ" strio.pos # => 3 # 3-byte character was read. strio.each_char {|char| chars.push(char) } chars # => ["ん", "に", "ち", "は"]
Wenn am Stream-Ende, wird der Block nicht aufgerufen
strio.eof? # => true strio.each_char {|char| fail 'Boo!' } strio.eof? # => true
Ohne Block wird ein neuer Enumerator zurückgegeben.
Verwandt: StringIO#each_byte, StringIO#each_codepoint, StringIO#each_line.
Source
static VALUE
strio_each_codepoint(VALUE self)
{
struct StringIO *ptr;
rb_encoding *enc;
unsigned int c;
int n;
RETURN_ENUMERATOR(self, 0, 0);
ptr = readable(self);
enc = get_enc(ptr);
while ((ptr = strio_to_read(self)) != NULL) {
c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
RSTRING_END(ptr->string), &n, enc);
ptr->pos += n;
rb_yield(UINT2NUM(c));
}
return self;
}
Mit übergebenem Block, ruft den Block mit jedem aufeinanderfolgenden Codepunkt aus self auf; setzt die Position auf das Stream-Ende; gibt self zurück.
Jeder Codepunkt ist der ganzzahlige Wert für ein Zeichen; gibt self zurück
codepoints = [] strio = StringIO.new('hello') strio.each_codepoint {|codepoint| codepoints.push(codepoint) } strio.eof? # => true codepoints # => [104, 101, 108, 108, 111] codepoints = [] strio = StringIO.new('тест') strio.each_codepoint {|codepoint| codepoints.push(codepoint) } codepoints # => [1090, 1077, 1089, 1090] codepoints = [] strio = StringIO.new('こんにちは') strio.each_codepoint {|codepoint| codepoints.push(codepoint) } codepoints # => [12371, 12435, 12395, 12385, 12399]
Position im Stream spielt eine Rolle
codepoints = [] strio = StringIO.new('こんにちは') strio.getc # => "こ" strio.pos # => 3 strio.each_codepoint {|codepoint| codepoints.push(codepoint) } codepoints # => [12435, 12395, 12385, 12399]
Wenn am Ende des Streams, wird der Block nicht aufgerufen
strio.eof? # => true strio.each_codepoint {|codepoint| fail 'Boo!' } strio.eof? # => true
Ohne Block wird ein neuer Enumerator zurückgegeben.
Verwandt: StringIO#each_byte, StringIO#each_char, StringIO#each_line.
Mit übergebenem Block, ruft den Block mit jeder verbleibenden Zeile (siehe „Position“ unten) im Stream auf; gibt self zurück.
Lässt die Stream-Position am Ende des Streams.
Keine Argumente
Wenn keine Argumente übergeben werden, werden Zeilen mit dem Standard-Aufzeichnungstrennzeichen (globale Variable $/, deren Anfangswert "\n" ist) gelesen.
strio = StringIO.new(TEXT) strio.each_line {|line| p line } strio.eof? # => true
Ausgabe
"First line\n" "Second line\n" "\n" "Fourth line\n" "Fifth line\n"
Argument sep
Wenn nur das String-Argument sep übergeben wird, werden Zeilen gelesen, wobei dieser String als Aufzeichnungstrennzeichen verwendet wird
strio = StringIO.new(TEXT) strio.each_line(' ') {|line| p line }
Ausgabe
"First " "line\nSecond " "line\n\nFourth " "line\nFifth " "line\n"
Argument limit
Wenn nur das Integer-Argument limit übergeben wird, werden Zeilen mit dem Standard-Aufzeichnungstrennzeichen gelesen; begrenzt auch die Größe (in Zeichen) jeder Zeile auf das angegebene Limit
strio = StringIO.new(TEXT) strio.each_line(10) {|line| p line }
Ausgabe
"First line" "\n" "Second lin" "e\n" "\n" "Fourth lin" "e\n" "Fifth line" "\n"
Argumente sep und limit
Wenn sowohl sep als auch limit übergeben werden, werden beide berücksichtigt
strio = StringIO.new(TEXT) strio.each_line(' ', 10) {|line| p line }
Ausgabe
"First " "line\nSecon" "d " "line\n\nFour" "th " "line\nFifth" " " "line\n"
Position
Wie oben erwähnt, liest und gibt die Methode each die nächste *verbleibende* Zeile im Stream zurück.
In den obigen Beispielen beginnt jedes strio-Objekt mit seiner Position am Anfang des Streams; aber in anderen Fällen kann die Position irgendwo sein (siehe StringIO#pos)
strio = StringIO.new(TEXT) strio.pos = 30 # Set stream position to character 30. strio.each_line {|line| p line }
Ausgabe
" line\n" "Fifth line\n"
In allen obigen Beispielen befindet sich die Stream-Position am Anfang eines Zeichens; in anderen Fällen muss dies nicht der Fall sein
s = 'こんにちは' # Five 3-byte characters. strio = StringIO.new(s) strio.pos = 3 # At beginning of second character. strio.each_line {|line| p line } strio.pos = 4 # At second byte of second character. strio.each_line {|line| p line } strio.pos = 5 # At third byte of second character. strio.each_line {|line| p line }
Ausgabe
"んにちは" "\x82\x93にちは" "\x93にちは"
Spezielle Aufzeichnungstrennzeichen
Wie einige Methoden in der Klasse IO, berücksichtigt StringIO.each zwei spezielle Aufzeichnungstrennzeichen; siehe Spezielle Zeilenseparatorwerte.
strio = StringIO.new(TEXT) strio.each_line('') {|line| p line } # Read as paragraphs (separated by blank lines).
Ausgabe
"First line\nSecond line\n\n" "Fourth line\nFifth line\n"
strio = StringIO.new(TEXT) strio.each_line(nil) {|line| p line } # "Slurp"; read it all.
Ausgabe
"First line\nSecond line\n\nFourth line\nFifth line\n"
Schlüsselwortargument chomp
Wenn das Schlüsselwortargument chomp auf true gesetzt ist (Standard ist false), wird der nachfolgende Zeilenumbruch (falls vorhanden) von jeder Zeile entfernt
strio = StringIO.new(TEXT) strio.each_line(chomp: true) {|line| p line }
Ausgabe
"First line" "Second line" "" "Fourth line" "Fifth line"
Wenn kein Block übergeben wird, wird ein neuer Enumerator zurückgegeben.
Verwandt: StringIO.each_byte, StringIO.each_char, StringIO.each_codepoint.
Source
static VALUE
strio_eof(VALUE self)
{
if (strio_to_read(self)) return Qfalse;
return Qtrue;
}
Gibt zurück, ob self am Ende des Streams positioniert ist
strio = StringIO.new('foo') strio.pos # => 0 strio.eof? # => false strio.read # => "foo" strio.pos # => 3 strio.eof? # => true strio.close_read strio.eof? # Raises IOError: not opened for reading
Verwandt: StringIO#pos.
Source
static VALUE
strio_external_encoding(VALUE self)
{
struct StringIO *ptr = StringIO(self);
return rb_enc_from_encoding(get_enc(ptr));
}
Gibt ein Encoding-Objekt zurück, das die Kodierung des Strings darstellt; siehe Kodierungen
strio = StringIO.new('foo') strio.external_encoding # => #<Encoding:UTF-8>
Gibt nil zurück, wenn self keinen String hat und sich im Schreibmodus befindet
strio = StringIO.new(nil, 'w+') strio.external_encoding # => nil
Source
static VALUE
strio_unimpl(int argc, VALUE *argv, VALUE self)
{
StringIO(self);
rb_notimplement();
UNREACHABLE;
}
Löst NotImplementedError aus.
Source
static VALUE
strio_nil(VALUE self)
{
StringIO(self);
return Qnil;
}
Gibt nil zurück; zur Kompatibilität mit IO.
Source
static VALUE
strio_self(VALUE self)
{
StringIO(self);
return self;
}
Gibt self zurück; zur Kompatibilität mit IO.
Source
static VALUE
strio_0(VALUE self)
{
StringIO(self);
return INT2FIX(0);
}
Gibt 0 zurück; zur Kompatibilität mit IO.
Source
static VALUE
strio_getbyte(VALUE self)
{
struct StringIO *ptr = readable(self);
int c;
if (eos_p(ptr)) {
return Qnil;
}
c = RSTRING_PTR(ptr->string)[ptr->pos++];
return CHR2FIX(c);
}
Liest und gibt das nächste Integer-Byte (nicht Zeichen) aus dem Stream zurück
s = 'foo' s.bytes # => [102, 111, 111] strio = StringIO.new(s) strio.getbyte # => 102 strio.getbyte # => 111 strio.getbyte # => 111
Gibt nil zurück, wenn das Ende des Streams erreicht ist
strio.eof? # => true strio.getbyte # => nil
Gibt ein Byte zurück, kein Zeichen
s = 'Привет' s.bytes # => [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] strio = StringIO.new(s) strio.getbyte # => 208 strio.getbyte # => 159 s = 'こんにちは' s.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] strio = StringIO.new(s) strio.getbyte # => 227 strio.getbyte # => 129
Source
static VALUE
strio_getc(VALUE self)
{
struct StringIO *ptr = readable(self);
rb_encoding *enc = get_enc(ptr);
VALUE str = ptr->string;
long pos = ptr->pos;
int len;
char *p;
if (eos_p(ptr)) {
return Qnil;
}
p = RSTRING_PTR(str)+pos;
len = rb_enc_mbclen(p, RSTRING_END(str), enc);
ptr->pos += len;
return enc_subseq(str, pos, len, enc);
}
Liest und gibt das nächste Zeichen (oder Byte; siehe unten) aus dem Stream zurück
strio = StringIO.new('foo') strio.getc # => "f" strio.getc # => "o" strio.getc # => "o"
Gibt nil zurück, wenn das Ende des Streams erreicht ist
strio.eof? # => true strio.getc # => nil
Gibt Zeichen zurück, keine Bytes
strio = StringIO.new('Привет') strio.getc # => "П" strio.getc # => "р" strio = StringIO.new('こんにちは') strio.getc # => "こ" strio.getc # => "ん"
In jedem der obigen Beispiele befindet sich der Stream am Anfang eines Zeichens; in anderen Fällen muss dies nicht der Fall sein
strio = StringIO.new('こんにちは') # Five 3-byte characters. strio.pos = 3 # => 3 # At beginning of second character; returns character. strio.getc # => "ん" strio.pos = 4 # => 4 # At second byte of second character; returns byte. strio.getc # => "\x82" strio.pos = 5 # => 5 # At third byte of second character; returns byte. strio.getc # => "\x93"
Source
static VALUE
strio_gets(int argc, VALUE *argv, VALUE self)
{
struct StringIO *ptr = readable(self);
struct getline_arg arg;
VALUE str;
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
if (NIL_P(ptr->string)) return Qnil;
return rb_enc_str_new(0, 0, get_enc(ptr));
}
str = strio_getline(&arg, ptr);
rb_lastline_set(str);
return str;
}
Liest und gibt eine Zeile aus dem Stream zurück; gibt nil zurück, wenn das Ende des Streams erreicht ist.
Nebeneffekte
-
Erhöht die Stream-Position um die Anzahl der gelesenen Bytes.
-
Weist den Rückgabewert der globalen Variablen
$_zu.
Wenn keine Argumente übergeben werden, liest es eine Zeile mit dem Standard-Aufzeichnungstrennzeichen (globale Variable $/,* deren Anfangswert "\n" ist)
strio = StringIO.new(TEXT) strio.pos # => 0 strio.gets # => "First line\n" strio.pos # => 11 $_ # => "First line\n" strio.gets # => "Second line\n" strio.read # => "\nFourth line\nFifth line\n" strio.eof? # => true strio.gets # => nil strio = StringIO.new('Привет') # Six 2-byte characters strio.pos # => 0 strio.gets # => "Привет" strio.pos # => 12
Argument sep
Wenn nur das String-Argument sep übergeben wird, liest es eine Zeile mit diesem String als Aufzeichnungstrennzeichen
strio = StringIO.new(TEXT) strio.gets(' ') # => "First " strio.gets(' ') # => "line\nSecond " strio.gets(' ') # => "line\n\nFourth "
Argument limit
Wenn nur das Integer-Argument limit übergeben wird, liest es eine Zeile mit dem Standard-Aufzeichnungstrennzeichen; begrenzt die Größe (in Zeichen) jeder Zeile auf das angegebene Limit
strio = StringIO.new(TEXT) strio.gets(10) # => "First line" strio.gets(10) # => "\n" strio.gets(10) # => "Second lin" strio.gets(10) # => "e\n"
Argumente sep und limit
Wenn sowohl sep als auch limit übergeben werden, werden beide berücksichtigt
strio = StringIO.new(TEXT) strio.gets(' ', 10) # => "First " strio.gets(' ', 10) # => "line\nSecon" strio.gets(' ', 10) # => "d "
Position
Wie oben erwähnt, liest und gibt die Methode gets die nächste Zeile im Stream zurück.
In den obigen Beispielen beginnt jedes strio-Objekt mit seiner Position am Anfang des Streams; aber in anderen Fällen kann die Position irgendwo sein
strio = StringIO.new(TEXT) strio.pos = 12 strio.gets # => "econd line\n"
Die Position muss nicht an einer Zeichengrenze liegen
strio = StringIO.new('Привет') # Six 2-byte characters. strio.pos = 2 # At beginning of second character. strio.gets # => "ривет" strio.pos = 3 # In middle of second character. strio.gets # => "\x80ивет"
Spezielle Aufzeichnungstrennzeichen
Wie einige Methoden in der Klasse IO, berücksichtigt die Methode gets zwei spezielle Aufzeichnungstrennzeichen; siehe Spezielle Zeilenseparatorwerte
strio = StringIO.new(TEXT) strio.gets('') # Read "paragraph" (up to empty line). # => "First line\nSecond line\n\n" strio = StringIO.new(TEXT) strio.gets(nil) # "Slurp": read all. # => "First line\nSecond line\n\nFourth line\nFifth line\n"
Schlüsselwortargument chomp
Wenn das Schlüsselwortargument chomp auf true gesetzt ist (Standard ist false), wird der nachfolgende Zeilenumbruch (falls vorhanden) aus der zurückgegebenen Zeile entfernt
strio = StringIO.new(TEXT) strio.gets # => "First line\n" strio.gets(chomp: true) # => "Second line"
Verwandt: each_line, readlines, Kernel#puts.
Source
static VALUE
strio_internal_encoding(VALUE self)
{
return Qnil;
}
Gibt nil zurück; zur Kompatibilität mit IO.
Source
static VALUE
strio_false(VALUE self)
{
StringIO(self);
return Qfalse;
}
Gibt false zurück; zur Kompatibilität mit IO.
Source
static VALUE
strio_get_lineno(VALUE self)
{
return LONG2NUM(StringIO(self)->lineno);
}
Gibt die aktuelle Zeilennummer in self zurück; siehe Zeilennummer.
Source
static VALUE
strio_set_lineno(VALUE self, VALUE lineno)
{
StringIO(self)->lineno = NUM2LONG(lineno);
return lineno;
}
Setzt die aktuelle Zeilennummer in self auf die angegebene new_line_number; siehe Zeilennummer.
Source
static VALUE
strio_nil(VALUE self)
{
StringIO(self);
return Qnil;
}
Gibt nil zurück; zur Kompatibilität mit IO.
Source
static VALUE
strio_get_pos(VALUE self)
{
return LONG2NUM(StringIO(self)->pos);
}
Gibt die aktuelle Position (in Bytes) zurück; siehe Position.
Source
static VALUE
strio_set_pos(VALUE self, VALUE pos)
{
struct StringIO *ptr = StringIO(self);
long p = NUM2LONG(pos);
if (p < 0) {
error_inval(0);
}
ptr->pos = p;
return pos;
}
Setzt die aktuelle Position (in Bytes); siehe Position.
Source
static VALUE
strio_pread(int argc, VALUE *argv, VALUE self)
{
VALUE rb_len, rb_offset, rb_buf;
rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf);
long len = NUM2LONG(rb_len);
long offset = NUM2LONG(rb_offset);
if (len < 0) {
rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
}
if (len == 0) {
if (NIL_P(rb_buf)) {
return rb_str_new("", 0);
}
return rb_buf;
}
if (offset < 0) {
rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
}
struct StringIO *ptr = readable(self);
if (outside_p(ptr, offset)) {
rb_eof_error();
}
if (NIL_P(rb_buf)) {
return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
}
long rest = RSTRING_LEN(ptr->string) - offset;
if (len > rest) len = rest;
rb_str_resize(rb_buf, len);
rb_enc_associate(rb_buf, rb_ascii8bit_encoding());
MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len);
return rb_buf;
}
Siehe IO#pread.
Source
static VALUE
strio_putc(VALUE self, VALUE ch)
{
struct StringIO *ptr = writable(self);
VALUE str;
check_modifiable(ptr);
if (RB_TYPE_P(ch, T_STRING)) {
if (NIL_P(ptr->string)) return ch;
str = rb_str_substr(ch, 0, 1);
}
else {
char c = NUM2CHR(ch);
if (NIL_P(ptr->string)) return ch;
str = rb_str_new(&c, 1);
}
strio_write(self, str);
return ch;
}
Siehe IO#putc.
Source
static VALUE
strio_read(int argc, VALUE *argv, VALUE self)
{
struct StringIO *ptr = readable(self);
VALUE str = Qnil;
long len;
int binary = 0;
switch (argc) {
case 2:
str = argv[1];
if (!NIL_P(str)) {
StringValue(str);
rb_str_modify(str);
}
/* fall through */
case 1:
if (!NIL_P(argv[0])) {
len = NUM2LONG(argv[0]);
if (len < 0) {
rb_raise(rb_eArgError, "negative length %ld given", len);
}
if (eos_p(ptr)) {
if (!NIL_P(str)) rb_str_resize(str, 0);
return len > 0 ? Qnil : rb_str_new(0, 0);
}
binary = 1;
break;
}
/* fall through */
case 0:
if (NIL_P(ptr->string)) return Qnil;
len = RSTRING_LEN(ptr->string);
if (len <= ptr->pos) {
rb_encoding *enc = get_enc(ptr);
if (NIL_P(str)) {
str = rb_str_new(0, 0);
}
else {
rb_str_resize(str, 0);
}
rb_enc_associate(str, enc);
return str;
}
else {
len -= ptr->pos;
}
break;
default:
rb_error_arity(argc, 0, 2);
}
if (NIL_P(str)) {
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
str = strio_substr(ptr, ptr->pos, len, enc);
}
else {
long rest = RSTRING_LEN(ptr->string) - ptr->pos;
if (len > rest) len = rest;
rb_str_resize(str, len);
MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
if (!binary) {
rb_enc_copy(str, ptr->string);
}
}
ptr->pos += RSTRING_LEN(str);
return str;
}
Siehe IO#read.
Source
static VALUE
strio_readlines(int argc, VALUE *argv, VALUE self)
{
VALUE ary, line;
struct StringIO *ptr = readable(self);
struct getline_arg arg;
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
}
ary = rb_ary_new();
while (!NIL_P(line = strio_getline(&arg, ptr))) {
rb_ary_push(ary, line);
}
return ary;
}
Siehe IO#readlines.
Source
static VALUE
strio_reopen(int argc, VALUE *argv, VALUE self)
{
rb_io_taint_check(self);
if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
return strio_copy(self, *argv);
}
return strio_init(argc, argv, StringIO(self), self);
}
Initialisiert den Stream mit dem gegebenen other (String oder StringIO) und mode neu; siehe IO.new
StringIO.open('foo') do |strio| p strio.string strio.reopen('bar') p strio.string other_strio = StringIO.new('baz') strio.reopen(other_strio) p strio.string other_strio.close end
Ausgabe
"foo" "bar" "baz"
Source
static VALUE
strio_rewind(VALUE self)
{
struct StringIO *ptr = StringIO(self);
ptr->pos = 0;
ptr->lineno = 0;
return INT2FIX(0);
}
Setzt die aktuelle Position und Zeilennummer auf Null; siehe Position und Zeilennummer.
Source
static VALUE
strio_seek(int argc, VALUE *argv, VALUE self)
{
VALUE whence;
struct StringIO *ptr = StringIO(self);
long amount, offset;
rb_scan_args(argc, argv, "11", NULL, &whence);
amount = NUM2LONG(argv[0]);
if (CLOSED(self)) {
rb_raise(rb_eIOError, "closed stream");
}
switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
case 0:
offset = 0;
break;
case 1:
offset = ptr->pos;
break;
case 2:
if (NIL_P(ptr->string)) {
offset = 0;
} else {
offset = RSTRING_LEN(ptr->string);
}
break;
default:
error_inval("invalid whence");
}
if (amount > LONG_MAX - offset || amount + offset < 0) {
error_inval(0);
}
ptr->pos = amount + offset;
return INT2FIX(0);
}
Setzt die Position auf den gegebenen Integer-offset (in Bytes), bezogen auf eine gegebene Konstante whence; siehe IO#seek.
Source
static VALUE
strio_set_encoding(int argc, VALUE *argv, VALUE self)
{
rb_encoding* enc;
struct StringIO *ptr = StringIO(self);
VALUE ext_enc, int_enc, opt;
argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);
if (NIL_P(ext_enc)) {
enc = rb_default_external_encoding();
}
else {
enc = rb_find_encoding(ext_enc);
if (!enc) {
rb_io_enc_t convconfig;
int oflags;
rb_io_mode_t fmode;
VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
enc = convconfig.enc2;
}
}
ptr->enc = enc;
if (!NIL_P(ptr->string) && WRITABLE(self) && !str_chilled_p(ptr->string)) {
rb_enc_associate(ptr->string, enc);
}
return self;
}
Source
static VALUE
strio_set_encoding_by_bom(VALUE self)
{
struct StringIO *ptr = StringIO(self);
if (!set_encoding_by_bom(ptr)) return Qnil;
return rb_enc_from_encoding(ptr->enc);
}
Setzt die Kodierung entsprechend der BOM (Byte Order Mark) im String.
Gibt self zurück, wenn die BOM gefunden wurde, andernfalls +nil.
Source
static VALUE
strio_size(VALUE self)
{
VALUE string = StringIO(self)->string;
if (NIL_P(string)) {
return INT2FIX(0);
}
return ULONG2NUM(RSTRING_LEN(string));
}
Gibt die Anzahl der Bytes im String in self zurück
StringIO.new('hello').size # => 5 # Five 1-byte characters. StringIO.new('тест').size # => 8 # Four 2-byte characters. StringIO.new('こんにちは').size # => 15 # Five 3-byte characters.
Source
static VALUE
strio_get_string(VALUE self)
{
return StringIO(self)->string;
}
Gibt den zugrunde liegenden String zurück
StringIO.open('foo') do |strio| p strio.string strio.string = 'bar' p strio.string end
Ausgabe
"foo" "bar"
Verwandt: StringIO#string= (weist den zugrunde liegenden String zu).
Source
static VALUE
strio_set_string(VALUE self, VALUE string)
{
struct StringIO *ptr = StringIO(self);
rb_io_taint_check(self);
ptr->flags &= ~FMODE_READWRITE;
StringValue(string);
ptr->flags = readonly_string_p(string) ? FMODE_READABLE : FMODE_READWRITE;
ptr->pos = 0;
ptr->lineno = 0;
RB_OBJ_WRITE(self, &ptr->string, string);
return string;
}
Ersetzt den gespeicherten String durch other_string und setzt die Position auf Null; gibt other_string zurück
StringIO.open('foo') do |strio| p strio.string strio.string = 'bar' p strio.string end
Ausgabe
"foo" "bar"
Verwandt: StringIO#string (gibt den gespeicherten String zurück).
Source
static VALUE
strio_get_sync(VALUE self)
{
StringIO(self);
return Qtrue;
}
Gibt true zurück; nur zur Kompatibilität mit anderen Stream-Klassen implementiert.
Source
static VALUE
strio_first(VALUE self, VALUE arg)
{
StringIO(self);
return arg;
}
Gibt das Argument unverändert zurück. Nur zur Kompatibilität mit IO.
Source
static VALUE
strio_get_pos(VALUE self)
{
return LONG2NUM(StringIO(self)->pos);
}
Gibt die aktuelle Position (in Bytes) zurück; siehe Position.
Source
static VALUE
strio_truncate(VALUE self, VALUE len)
{
VALUE string = writable(self)->string;
long l = NUM2LONG(len);
long plen;
if (l < 0) {
error_inval("negative length");
}
if (NIL_P(string)) return 0;
plen = RSTRING_LEN(string);
rb_str_resize(string, l);
if (plen < l) {
MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
}
return INT2FIX(0);
}
Kürzt den Puffer-String auf maximal integer Bytes. Der Stream muss zum Schreiben geöffnet sein.
Source
static VALUE
strio_ungetbyte(VALUE self, VALUE c)
{
struct StringIO *ptr = readable(self);
check_modifiable(ptr);
if (NIL_P(ptr->string)) return Qnil;
if (NIL_P(c)) return Qnil;
if (RB_INTEGER_TYPE_P(c)) {
/* rb_int_and() not visible from exts */
VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
const char cc = NUM2INT(v) & 0xFF;
strio_unget_bytes(ptr, &cc, 1);
}
else {
StringValue(c);
strio_unget_string(ptr, c);
}
return Qnil;
}
Schiebt ein 8-Bit-Byte zurück („unshifts“) in den Stream; siehe Byte IO.
Source
static VALUE
strio_ungetc(VALUE self, VALUE c)
{
struct StringIO *ptr = readable(self);
rb_encoding *enc, *enc2;
check_modifiable(ptr);
if (NIL_P(ptr->string)) return Qnil;
if (NIL_P(c)) return Qnil;
if (RB_INTEGER_TYPE_P(c)) {
int len, cc = NUM2INT(c);
char buf[16];
enc = rb_enc_get(ptr->string);
len = rb_enc_codelen(cc, enc);
if (len <= 0) {
rb_enc_uint_chr(cc, enc); /* to raise an exception */
UNREACHABLE;
}
rb_enc_mbcput(cc, buf, enc);
return strio_unget_bytes(ptr, buf, len);
}
else {
StringValue(c);
if (RSTRING_LEN(c) == 0) return Qnil;
enc = rb_enc_get(ptr->string);
enc2 = rb_enc_get(c);
if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
c = rb_str_conv_enc(c, enc2, enc);
}
strio_unget_string(ptr, c);
return Qnil;
}
}
Schiebt ein Zeichen oder eine Ganzzahl zurück („unshifts“) in den Stream; siehe Zeichen IO.
Source
static VALUE
strio_write_m(int argc, VALUE *argv, VALUE self)
{
long len = 0;
while (argc-- > 0) {
/* StringIO can't exceed long limit */
len += strio_write(self, *argv++);
}
return LONG2NUM(len);
}
Hängt den gegebenen String an den zugrunde liegenden Puffer-String an. Der Stream muss zum Schreiben geöffnet sein. Wenn das Argument kein String ist, wird es mithilfe von to_s in einen String konvertiert. Gibt die Anzahl der geschriebenen Bytes zurück. Siehe IO#write.