Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Unified Diff: runtime/bin/file_impl.dart

Issue 10542102: Add buffering to _FileInputStream implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase to current bleeding-edge Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/standalone/io/file_input_stream_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/file_impl.dart
diff --git a/runtime/bin/file_impl.dart b/runtime/bin/file_impl.dart
index 9e9b6340a52667c997180b6d7d5a774f53dcbb44..bc83f38cb885d594b20f1d82d7d68257e00da57f 100644
--- a/runtime/bin/file_impl.dart
+++ b/runtime/bin/file_impl.dart
@@ -3,88 +3,138 @@
// BSD-style license that can be found in the LICENSE file.
class _FileInputStream extends _BaseDataInputStream implements InputStream {
- _FileInputStream(String name) {
+ _FileInputStream(String name)
+ : _data = [],
+ _position = 0,
+ _filePosition = 0 {
var file = new File(name);
- _data = [];
- _position = 0;
- var chained = file.open(FileMode.READ).chain((openedFile) {
- return _readDataFromFile(openedFile);
- });
- chained.handleException((e) {
+ var future = file.open(FileMode.READ);
+ future.handleException((e) {
_reportError(e);
return true;
});
+ future.then(_setupOpenedFile);
}
- _FileInputStream.fromStdio(int fd) {
+ _FileInputStream.fromStdio(int fd)
+ : _data = [],
+ _position = 0,
+ _filePosition = 0 {
assert(fd == 0);
- var file = _File._openStdioSync(fd);
- _data = [];
- _position = 0;
- _readDataFromFile(file).handleException((e) {
+ _setupOpenedFile(_File._openStdioSync(fd));
+ }
+
+ void _setupOpenedFile(RandomAccessFile openedFile) {
+ _openedFile = openedFile;
+ if (_streamMarkedClosed) {
+ // This input stream has already been closed.
+ _fileLength = 0;
+ _closeFile();
+ return;
+ }
+ var futureOpen = _openedFile.length();
+ futureOpen.then((len) {
+ _fileLength = len;
+ _fillBuffer();
+ });
+ futureOpen.handleException((e) {
_reportError(e);
return true;
});
}
- Future<RandomAccessFile> _closeAfterRead(RandomAccessFile openedFile) {
- return openedFile.close().transform((ignore) {
+ void _closeFile() {
+ if (_openedFile == null) {
_streamMarkedClosed = true;
- _checkScheduleCallbacks();
- return openedFile;
- });
+ return;
+ }
+ if (available() == 0) _cancelScheduledDataCallback();
+ if (!_openedFile.closed) {
+ _openedFile.close().then((ignore) {
+ _streamMarkedClosed = true;
+ _checkScheduleCallbacks();
+ });
+ }
}
- Future<RandomAccessFile> _readDataFromFile(RandomAccessFile openedFile) {
- return openedFile.length().chain((length) {
- var contents = new Uint8List(length);
- if (length != 0) {
- return openedFile.readList(contents, 0, length).chain((read) {
- if (read != length) {
- throw new FileIOException(
- 'Failed reading file contents in FileInputStream');
- } else {
- _data = contents;
- }
- return _closeAfterRead(openedFile);
- });
- } else {
- return _closeAfterRead(openedFile);
+ void _fillBuffer() {
+ Expect.equals(_position, _data.length);
+ if (_openedFile == null) return; // Called before the file is opened.
+ int size = Math.min(_bufferLength, _fileLength - _filePosition);
+ if (size == 0) {
+ _closeFile();
+ return;
+ }
+ if (_data.length != size) {
+ _data = new Uint8List(size);
+ }
+ var future = _openedFile.readList(_data, 0, _data.length);
+ future.then((read) {
+ _filePosition += read;
+ if (read != _data.length) {
+ _data.removeRange(read, _data.length - read);
+ }
+ _position = 0;
+
+ if (_fileLength == _filePosition) {
+ _closeFile();
}
+ _checkScheduleCallbacks();
});
}
int available() {
- return _closed ? 0 : _data.length - _position;
+ return closed ? 0 : _data.length - _position;
}
void pipe(OutputStream output, [bool close = true]) {
_pipe(this, output, close: close);
}
+ void _finishRead() {
+ if (_position == _data.length && !_streamMarkedClosed) {
+ _fillBuffer();
+ } else {
+ _checkScheduleCallbacks();
+ }
+ }
+
List<int> _read(int bytesToRead) {
- List<int> result = new Uint8List(bytesToRead);
- result.setRange(0, bytesToRead, _data, _position);
- _position += bytesToRead;
- _checkScheduleCallbacks();
+ List<int> result;
+ if (_position == 0 && bytesToRead == _data.length) {
+ result = _data;
+ _data = [];
+ } else {
+ result = new Uint8List(bytesToRead);
+ result.setRange(0, bytesToRead, _data, _position);
+ _position += bytesToRead;
+ }
+ _finishRead();
return result;
}
int _readInto(List<int> buffer, int offset, int len) {
buffer.setRange(offset, len, _data, _position);
_position += len;
- _checkScheduleCallbacks();
+ _finishRead();
return len;
}
void _close() {
- if (_closed) return;
- _closed = true;
+ _data = [];
+ _position = 0;
+ _filePosition = 0;
+ _fileLength = 0;
+ _closeFile();
}
+ static final int _bufferLength = 64 * 1024;
+
+ RandomAccessFile _openedFile;
List<int> _data;
int _position;
- bool _closed = false;
+ int _filePosition;
+ int _fileLength;
}
@@ -712,13 +762,13 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<RandomAccessFile> close() {
Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
_ensureFileService();
List request = new List(2);
request[0] = _FileUtils.CLOSE_REQUEST;
request[1] = _id;
// Set the id_ to 0 (NULL) to ensure the no more async requests
- // can be issues for this file.
+ // can be issued for this file.
_id = 0;
return _fileService.call(request).transform((result) {
if (result != -1) {
@@ -742,7 +792,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<int> readByte() {
_ensureFileService();
Completer<int> completer = new Completer<int>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(2);
request[0] = _FileUtils.READ_BYTE_REQUEST;
request[1] = _id;
@@ -777,7 +827,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
});
return completer.future;
};
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(3);
request[0] = _FileUtils.READ_LIST_REQUEST;
request[1] = _id;
@@ -827,7 +877,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
});
return completer.future;
}
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(3);
request[0] = _FileUtils.WRITE_BYTE_REQUEST;
request[1] = _id;
@@ -868,7 +918,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
});
return completer.future;
}
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List result;
try {
@@ -922,7 +972,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
[Encoding encoding = Encoding.UTF_8]) {
_ensureFileService();
Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(3);
request[0] = _FileUtils.WRITE_STRING_REQUEST;
request[1] = _id;
@@ -948,7 +998,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<int> position() {
_ensureFileService();
Completer<int> completer = new Completer<int>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(2);
request[0] = _FileUtils.POSITION_REQUEST;
request[1] = _id;
@@ -973,7 +1023,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<RandomAccessFile> setPosition(int position) {
_ensureFileService();
Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(3);
request[0] = _FileUtils.SET_POSITION_REQUEST;
request[1] = _id;
@@ -998,7 +1048,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<RandomAccessFile> truncate(int length) {
_ensureFileService();
Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(3);
request[0] = _FileUtils.TRUNCATE_REQUEST;
request[1] = _id;
@@ -1023,7 +1073,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<int> length() {
_ensureFileService();
Completer<int> completer = new Completer<int>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(2);
request[0] = _FileUtils.LENGTH_REQUEST;
request[1] = _id;
@@ -1048,7 +1098,7 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
Future<RandomAccessFile> flush() {
_ensureFileService();
Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
- if (_isClosed) return _completeWithClosedException(completer);
+ if (closed) return _completeWithClosedException(completer);
List request = new List(2);
request[0] = _FileUtils.FLUSH_REQUEST;
request[1] = _id;
@@ -1077,10 +1127,10 @@ class _RandomAccessFile extends _FileBase implements RandomAccessFile {
}
}
- bool get _isClosed() => _id == 0;
+ bool get closed() => _id == 0;
void _checkNotClosed() {
- if (_isClosed) {
+ if (closed) {
throw new FileIOException("File closed '$_name'");
}
}
« no previous file with comments | « no previous file | tests/standalone/io/file_input_stream_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698