Использовать str.form_utf8 не получится, т.к. весь огромный файл в память не лезет, а читать по строкам не имеет смысла, т.к. там нет переносов строк.
А Reader.chars у нас depricated.
Гуглопоиск в основном даёт ссылки на stackoverflow где по сути предлагают тот же str.form_utf8.
Code that does not care about processing data incrementally can use
Read::read_to_string
instead. Code that does care presumably also wants to control its buffering strategy and work with&[u8]
and&str
slices that are as large as possible, rather than onechar
at a time. It should be based on thestr::from_utf8
function as well as thevalid_up_to
anderror_len
methods of theUtf8Error
type. One tricky aspect is dealing with cases where a singlechar
is represented in UTF-8 by multiple bytes where those bytes happen to be split across separateread
calls / buffer chunks. (Utf8Error::error_len
returningNone
indicates that this may be the case.) Theutf-8
crate solves this, but in order to be flexible provides an API that probably has too much surface to be included in the standard library.
С виду похоже на описание твоего случая. Т.е. читаешь по кускам в байтовый буфер нужного тебе размера, а потом при помощи utf-8
получаешь что-то максимально похожее на строку из этого дела. Главное ошибки “склейки” блоков корретно обрабатывать.
Ничего проще я тоже нагуглить не могу.
Это я читал.
Я думал может есть готовое, чтобы своё не велосипедить.
На StackOverflow есть такой вариант
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
let mut buf = Vec::<u8>::new();
while f.read_until(b'\n', &mut buf).expect("read_until failed") != 0 {
// this moves the ownership of the read data to s
// there is no allocation
let s = String::from_utf8(buf).expect("from_utf8 failed");
for c in s.chars() {
println!("Character: {}", c);
}
// this returns the ownership of the read data to buf
// there is no allocation
buf = s.into_bytes();
buf.clear();
}
}
Такое решение под изначальный вопрос вряд ли подходит.
Тогда можно использовать read()
и читать нужное число байтов кратное 4, затем from_utf8_lossy
-> trim_right_matches
-> chars
.
Хм, почему кратное четырем? Там же utf-8, а не utf32.
И зачем trim? И чем лучше варианта с utf-8
пакетом выше?
По ответу я решил, что это не подходит, хотя мой вариант получается сложнее. Разе UTF-8 не до 4 байт?
Я так понял что подходит, просто хотелось прям удобное и готовое решение, а не собирать самому из кусков.
До четырех, да, но я не понял как именно отбрасывание “мусорного” хвоста должно работать. Вроде бы trim_right_matches
не про это же.
Читать файл нужно на сколько, сколько в буфер влезет, но в конце прочитанной строки в буфере, в пределах максимальной длинны UTF8, может отказаться часть байт недочитанного UTF8 символа.
которые нужно будет перед следующей заливкой буфера поставить в начало и, в место, оставшееся в буфере после них, дочитывать