BufferedStream原理
时间: 2024-05-31 15:10:12 浏览: 9
BufferedStream是一个带缓冲区的流,用于提高读写性能。它通过在内存中维护一个缓冲区(byte数组)来减少对底层数据流的访问次数,从而提高读写效率。
当我们向BufferedStream中写入数据时,数据并不会直接写入到底层数据流中,而是先写入到缓冲区中,直到缓冲区满了或者我们显式地调用Flush方法将缓冲区中的数据写入到底层数据流中。同样地,当我们从BufferedStream中读取数据时,数据也是从缓冲区中读取,如果缓冲区中没有数据,它会先从底层数据流中读取一定量的数据到缓冲区中,然后再从缓冲区中读取数据。
由于BufferedStream减少了对底层数据流的访问次数,因此可以大大提高读写效率,特别是在大量读写小数据块的情况下,效果更为明显。同时,由于缓冲区的存在,我们还可以通过设置不同大小的缓冲区来进一步优化读写性能。
相关问题
怎么读取BufferedStream
使用 BufferedStream 读取数据时,可以使用类似于 FileStream 的方式进行读取,同时也可以使用 BinaryReader 或者 StreamReader 类来读取数据。
下面是一个使用 BufferedStream 和 BinaryReader 读取文件数据的示例:
```csharp
using (FileStream fs = new FileStream("test.txt", FileMode.OpenOrCreate))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (BinaryReader br = new BinaryReader(bs))
{
int intValue = br.ReadInt32();
string stringValue = br.ReadString();
float floatValue = br.ReadSingle();
Console.WriteLine(intValue);
Console.WriteLine(stringValue);
Console.WriteLine(floatValue);
}
}
}
```
这个示例中,首先创建了一个 FileStream 对象,然后将其传递给 BufferedStream 构造函数创建 BufferedStream 对象,最后将 BufferedStream 对象传递给 BinaryReader 构造函数创建 BinaryReader 对象。接着就可以使用 BinaryReader 的 ReadInt32、ReadString 和 ReadSingle 方法逐个读取数据了。
需要注意的是,在使用 BufferedStream 读取数据时,需要保证读取的字节数不超过 BufferedStream 缓存的大小,否则可能会导致数据不完整。此外,在读取完成后,需要将 BufferedStream 中缓存的数据全部刷新到 FileStream 中,以确保所有数据都已经被写入到文件中。可以使用 BufferedStream 的 Flush 方法来完成这个操作。
fun Context.readTxtFileByLinesWithProgress(uri: Uri): Sequence<Pair<String, Float>> { val inputStream = this.contentResolver.openInputStream(uri)!! val totalBytes = inputStream.available().toFloat() val bufferedStream = BufferedInputStream(inputStream) val reader = InputStreamReader(bufferedStream, Charsets.UTF_8) val bufferedReader = BufferedReader(reader) return sequence { var readBytes = 0f bufferedReader.useLines { lines -> lines.forEach { line -> readBytes += line.toByteArray(Charsets.UTF_8).size.toFloat() val progress = readBytes / totalBytes * 100 yield(line to progress) } } bufferedStream.close() reader.close() bufferedReader.close() } } 实现倒叙
可以通过将 `yield(line to progress)` 改为 `yield(line to totalBytes - readBytes)` 实现倒序。
下面是修改后的代码:
```kotlin
fun Context.readTxtFileByLinesWithProgress(uri: Uri): Sequence<Pair<String, Float>> {
val inputStream = this.contentResolver.openInputStream(uri)!!
val totalBytes = inputStream.available().toFloat()
val bufferedStream = BufferedInputStream(inputStream)
val reader = InputStreamReader(bufferedStream, Charsets.UTF_8)
val bufferedReader = BufferedReader(reader)
return sequence {
var readBytes = 0f
val lines = bufferedReader.useLines { it.toList().asReversed() }
lines.forEach { line ->
readBytes += line.toByteArray(Charsets.UTF_8).size.toFloat()
val progress = totalBytes - readBytes
yield(line to progress)
}
bufferedStream.close()
reader.close()
bufferedReader.close()
}
}
```
注意,这里使用了 `useLines` 函数中的 `toList()` 将所有行读入内存并反转,因此在处理大文件时可能会有性能问题。如果需要处理大文件,可以考虑逐行倒序读取并处理。