Einzelnen Beitrag anzeigen

blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: BufferedReader in Firemonkey?

  Alt 10. Dez 2014, 18:11
Vielen Dank für den Hinweis mit Java2OP! Ich habe dieses Tool noch nicht gekannt - hätte nicht gedacht, dass das Verwenden der Android API so einfach sein kann


Bzgl. "Blockierungsfrei lesen selbst programmieren" - das habe ich schon versucht. Allerdings ging das (wie in StackOverflow beschrieben) nur mit der JInputStream.available() Funktion, die laut Javadokumentation nicht für diesen Zweck verwendet werden soll, da der Wert nur eine grobe Schätzung ist - in der Tat haben manche Geräte wegen der schlechten Schätzung dauerhaft blockiert oder nie gelesen, da available() bei manchen Geräten immer 0 oder immer >0 war.

Daher war meine Absicht, den BufferedReader zu verwenden, da das die einzige saubere Möglichkeit ist, einen Stream zuverlässig blockierungsfrei zu lesen.

Der Vollständigkeit halber meinen alten Code, der wegen der schlechten Schätzung von available() nicht auf allen Geräten läuft:
Delphi-Quellcode:

var // of TBufLineJStream
  buf: TJavaArray<Byte>;
  FStream: JInputStream;
  FCurIncompleteString: String;
  FReadLines: TQueue<String>;

const // of TBufLineJStream
  BufferSize = 65536;

procedure TBufLineJStream._ReadFromStream;
var
  c: Char;
  i, readCount: integer;
begin
  while FStream.available > 0 do
  begin
    readCount := FStream.read(buf, 0, BufferSize);
    for i := 0 to readCount-1 do
    begin
      c := Chr(buf.Items[i]);
      if c = #13 then
      begin
        // The line is complete
        FReadLines.Enqueue(FCurIncompleteString);
        FCurIncompleteString := '';
      end
      else
      begin
        // The line is not complete yet
        FCurIncompleteString := FCurIncompleteString + c;
      end;
    end;
  end;
end;

function TBufLineJStream.ReadLineNonBlocking(var outStr: string): boolean;
begin
  _ReadFromStream;

  result := FReadLines.Count > 0;
  if result then outStr := FReadLines.Dequeue;
end;
Die Dokumentation von Java warnt vor eer Verwendung von available() um blockierungsfreies Lesen zu realisieren:

Zitat:
[...]

Note that this method provides such a weak guarantee that it is not very useful in practice.

Firstly, the guarantee is "without blocking for more input" rather than "without blocking": a read may still block waiting for I/O to complete — [...]

[...]

The default implementation of this method in InputStream always returns 0. Subclasses should override this method if they are able to indicate the number of bytes available.
Daniel Marschall
  Mit Zitat antworten Zitat