Форум программистов, компьютерный форум, киберфорум
Rust
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232

Задача. Сохранить в файл вектор чисел, затем позиционировать на нужном элементе и изменить его

18.05.2024, 22:38. Показов 1549. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
То есть нужно сохранять буфер из чисел в файл, затем позиционировать на нужной позиции, изменить число, добавить в конец новое число, удалить из середины. И этот функционал нужен с разными типами данных. Кто делал подобное, можете подсказать как это сделать?
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.05.2024, 22:38
Ответы с готовыми решениями:

Как прочитать exe файл, а затем сохранить его?
подскажите как прочитать exe файл, затем хранить его как некий набор символов, а затем восстановить файл из этих данных пробовал...

Открыть с восстановлением doc файл, а затем сохранить его
Всем здравствуйте! Имеется каталог C:\1 , в нем иногда попадаются битые doc файлы. Как организовать код чтобы открывал и сохранял doc...

Как сохранить список в бинарный файл, и затем прочитать его из файла?
как сохранить список в бинарный файл, и затем прочитать его из файла???

14
Эксперт JS
 Аватар для DrType
6553 / 3624 / 1075
Регистрация: 07.09.2019
Сообщений: 5,877
Записей в блоге: 1
19.05.2024, 18:56
Например, так:
Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use std::fmt::{Display, Debug};
use std::fs::{OpenOptions, File};
use std::io::{BufWriter, BufReader, Write, BufRead};
use std::str::FromStr;
 
fn write_to_file<T: Display>(arr: Vec<T>, file_path: &str) {
    let file = OpenOptions::new()
        .write(true)
        .truncate(true)
        .open(file_path)
        .expect(format!("unable to open file {}", file_path).as_str());
    let mut writer = BufWriter::new(file);
 
    for el in arr {
        writeln!(writer, "{}", el.to_string()).expect("unable to write");
    }
}
 
fn read_from_file<T: FromStr>(file_path: &str) -> Vec<T> where <T as FromStr>::Err: Debug {
    let file = File::open(file_path).expect("file not found.");
    let reader = BufReader::new(file);
 
    let results = reader
        .lines()
        .map(|line| T::from_str(&line.unwrap()).unwrap())
        .collect();
    results
}
 
fn main() {
    let file_path = "test.txt";
    let arr = vec![1, 2, 3];
    write_to_file(arr, file_path);
    let mut saved = read_from_file::<i64>(file_path);
 
    saved.push(1);
    saved.remove(2);
    saved[0] = 3;
 
    write_to_file(saved, file_path);
}
3
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232
20.05.2024, 14:28  [ТС]
Не совсем то что нужно, вернее совсем не то что нужно. Это частный случай, а нужен более универсальный подход.

Можно описать структуру с обобщённым типом, например
Rust
1
2
3
4
5
6
7
struct WorkFile<Tp>
where Tp: AsRef<[u8]> // FromPrimitive + ToPrimitive
{
  file: File,
  path: String,
  data: Vec<Tp>
}
Далее при записи данных нужно конвертировать их в &[u8] и записывать в файл побайтно, так же читать и преобразовывать обратно в нужный тип.
Но числовые типы не поддерживают AsRef<[u8]>, а если FromPrimitive + ToPrimitive то применять .to_ne_bytes()
Вот функция преобразования разных типов в срез &[u8]
Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use std::mem;
 
fn to_bytes<T: ?Sized>(value: &T) -> &[u8]
where
    T: AsRef<[u8]>,
{
    value.as_ref()
}
 
fn to_bytes_for_numeric<T: ?Sized>(value: &T) -> &[u8]
where
    T: Copy + std::fmt::Debug,
{
    let size = mem::size_of_val(value);
    let mut buffer = vec![0; size as usize].into_boxed_slice();
    unsafe {
        match *value {
            i if i == i32::min_value()..=i32::max_value() => {
                let ptr = buffer.as_mut_ptr() as *mut i32;
                ptr.write(*value as i32);
            },
            f if f == f32::min_value()..=f32::max_value() => {
                let ptr = buffer.as_mut_ptr() as *mut f32;
                ptr.write(*value as f32);
            },
            _ => panic!("Unsupported type"),
        }
        std::slice::from_raw_parts(buffer.as_ptr(), size as usize)
    }
}
 
fn main() {
    let i: i32 = 42;
    let f: f32 = 3.14;
    let s: &str = "Hello, world!";
 
    println!("{:?}", to_bytes(&s)); // Использует AsRef<[u8]>
    println!("{:?}", to_bytes_for_numeric(&i)); // Специальная обработка для чисел
    println!("{:?}", to_bytes_for_numeric(&f)); // Специальная обработка для чисел
}
Но я не хочу это использовать мне нужна без шаманства с unsafe
0
Заблокирован
20.05.2024, 19:19
Многое зависит от того, как вы хотите хранить данные, каков их размер, как вы хотите их изменять.
Например можно использовать библиотеку для сериализации данных. Если это просто небольшой массив известной длины, то можно хранить его как сырые данные, то есть просто числа в файле. Много зависит от того, как и что вам конкретно нужно.
1
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232
20.05.2024, 21:23  [ТС]
Цитата Сообщение от Гай Посмотреть сообщение
Многое зависит от того, как вы хотите хранить данные
Задача на самом деле была следующая: Надо что-то типа класса как в ООП языках, чтобы можно указать тип данных и путь к файлу, затем загружать данные с возможностью указания позиции и размера, так же удаление, добавление, изменение данных. В принципе я уже это реализовал что и хотел.
0
240 / 189 / 32
Регистрация: 02.07.2020
Сообщений: 142
21.05.2024, 04:55
я так понимаю, вам нужно определить собственный трейт. Очень грубо говоря (особенно по части типов возврата ) вот так.

Rust
1
2
3
4
trait Serializable {
    fn serialize(&self, writer: &mut impl Write) -> bool;
    fn deserialize(reader: &mut impl Read) -> Option<Self> where Self: Sized;
}
А потом реализовать его для всех нужных типов. например (опять же, грубо говоря)

Rust
1
2
3
4
5
6
7
8
9
10
11
impl Serializable for usize {
    fn serialize(&self, writer: &mut impl Write) -> bool {
        writer.write(&self.to_ne_bytes()).is_ok()
    }
 
    fn deserialize(reader: &mut impl Read) -> Option<Self> {
        let mut buf = [0; 8];
        reader.read(&mut buf).ok()?;
        Some(Self::from_ne_bytes(buf))
    }
}
И использовать именно его вместо AsRef

Rust
1
assert!(42usize.serialize(&mut file));
Rust
1
let x = usize::deserialize(&mut file).unwrap();
2
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232
21.05.2024, 08:47  [ТС]
Цитата Сообщение от extrn Посмотреть сообщение
я так понимаю, вам нужно определить собственный трейт
Спасибо. Вот приятно видеть когда правильно понимают и дают дельные советы.

Да как и говорят, что в Rust всё делается через одно место, а именно trait. И я реализовал это через trait.
Вот тестовый пример:
Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
pub use std::path::Path;
use std::fs::{File, OpenOptions};
use std::io::{Result, Seek, SeekFrom, Write};
 
/// Реализация преобразования в байты
/// .to_bytes()->Vec\<u8\> 
trait ToBytes {
  fn to_bytes(&self)->Vec<u8>;
}
 
impl ToBytes for i32 {
  fn to_bytes(&self)->Vec<u8> {
    self.to_ne_bytes().to_vec()
  }
}
impl ToBytes for f32 {
  fn to_bytes(&self)->Vec<u8> {
    self.to_ne_bytes().to_vec()
  }
}
 
struct WorkFile<Tp: ToBytes> {
  file: File,
  path: String,
  data: Vec<Tp>,
}
 
impl<Tp: ToBytes> WorkFile<Tp> {
  pub fn open(pth: &str) -> Result<Self> {
    let file = OpenOptions::new()
        .read(true).write(true).create(true).open(pth)?;
    Ok(Self {
      file,
      path: pth.to_string(),
      data: Vec::new(),
    })
  }
  pub fn seek(&mut self, pos: u64) -> Result<u64> {
    self.file.seek(SeekFrom::Start(pos))
  }
  pub fn save(&mut self) -> Result<()> {
    for item in &self.data {
      self.file.write_all(&item.to_bytes())?;
    }
    Ok(())
  }
  pub fn add(&mut self,value:Tp){
    self.data.push(value)
  }
}
 
fn main() {
  let mut mf = WorkFile::<f32>::open("d:/zzz/data.i32").unwrap();
 
  mf.add(1.0);
  mf.add(2.0);
  mf.add(3.0);
 
  match mf.seek(40) {
    Ok(_) => match mf.save() {
      Ok(_) => println!("Данные успешно сохранены"),
      Err(e) => println!("Ошибка при сохранении данных: {}", e),
    },
    Err(err) => println!("Ошибка {}", err),
  }
 
  println!("{}, {:?}", mf.path, mf.data);
}
extrn, а у вас есть желание помочь в разработке языка, базы данных и сервера на Rust?
0
240 / 189 / 32
Регистрация: 02.07.2020
Сообщений: 142
21.05.2024, 09:55
А нам, отвечающим, нравится, когда вопрос задан четко и недвусмысленно, чтобы догадываться не пришлось
Спасибо за предложение, но, увы, своей работы хватает. А вам удачи с таким амбициозным проектом.
0
Заблокирован
22.05.2024, 11:11
Вообще изменение данных в файле с помощью команды seek - это порочная практика. Вероятность ошибки весьма велика.
Лучше читать данные и парсить их, потом изменять и уже записывать в файл.
3
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232
23.05.2024, 07:57  [ТС]
Цитата Сообщение от extrn Посмотреть сообщение
А вам удачи с таким амбициозным проектом.
Вам спасибо, за добрые пожелания
Цитата Сообщение от extrn Посмотреть сообщение
А нам, отвечающим, нравится, когда вопрос задан четко и недвусмысленно, чтобы догадываться не пришлось
Вы затронули неприятную проблему человеческой психологии. Дело в том, что задающий может чётко сформулировать вопрос только в том случае если уже знает ответ на него и ему нужно лишь подтверждение своей догадки, а когда не знаешь ответ то и вопрос сформулировать как надо не получится, только в процессе продумывания и выяснения получается найти ответ на свой вопрос и понимание каким он должен был быть.

Я перед тем как тут задать вопрос спрашивал по разному GPT и получал разные ответы как можно сделать, но это были всегда частные ответы для определённого типа, а мне нужно было найти подход чтобы был один интерфейс для работы со всеми стандартными типами данных. Поэтому пришлось тут задать общий вопрос, так как я не мог тогда ещё сформулировать чётко что мне надо так как не знал как это можно реализовать.
Цитата Сообщение от Гай Посмотреть сообщение
Вообще изменение данных в файле с помощью команды seek - это порочная практика. Вероятность ошибки весьма велика.
Лучше читать данные и парсить их, потом изменять и уже записывать в файл.
А вот тут вы не правы и те кто вам лайки поставили тоже. Видимо у вас нет просто опыта программирования на низком уровне разных драйверов работы с медиа(аудио, видео) файлами, с базами данных и др. сложными программами. Нельзя утверждать, что это порочная практика, так как в этом мире всё взаимосвязано и одни вещи нужны для других и тд. Вот уберите из языка низкого уровня возможность позиционирования в файле и как тогда вы реализуете потоковое воспроизведение аудио и видео с возможностью прокрутки к нужному месту или в базе данных как быстро получить значение не загружая весь гигабайтный файл. Вот именно. Поэтому только глупец может утверждать, что позиционирование в файле это порочная практика..

ЗЫ. Кстати вероятность ошибки при позиционировании минимальна, если всё правильно рассчитывать. Иначе вы бы сейчас не могли прокручивать аудио, видео и другие функции работы с большими данными были бы не реальны просто.
0
Заблокирован
24.05.2024, 07:11
pgb, начнем с того, что я,написал об изменении данных в файле, вы же говорите только об их чтении
0
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232
24.05.2024, 10:21  [ТС]
Цитата Сообщение от Гай Посмотреть сообщение
начнем с того, что я,написал об изменении данных в файле, вы же говорите только об их чтении
Нет, мы закончим, я подобную глупость обсуждать, что позиционирование в файле это порочная практика не собираюсь.

ЗЫ. Позиционирование используется не только для чтения, для изменения тоже. И я об этом говорил и приводил пример работы с БД. Если вы не в состояние понимать, что читаете это ваши проблемы. Кстати в тестовом примере что я привёл выше именно изменение с позиционированием.
0
 Аватар для pgb
-508 / 32 / 0
Регистрация: 22.09.2015
Сообщений: 1,232
25.05.2024, 17:40  [ТС]
Цитата Сообщение от pgb Посмотреть сообщение
разных драйверов работы с медиа
Пардон, поправочка, не драйверов конечно же, а кодеков.
0
27.05.2024, 09:07

Не по теме:

модеры, расчехляйте уже плюсометы

0
Заблокирован
20.06.2024, 17:33
Цитата Сообщение от pgb Посмотреть сообщение
ЗЫ. Позиционирование используется не только для чтения, для изменения тоже. И я об этом говорил и приводил пример работы с БД.
Что там с БД?
Как это используется в БД? В БД используются таблицы с доступом по ключу. Причём тут слепое позиционирование в файле я не знаю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.06.2024, 17:33
Помогаю со студенческими работами здесь

Как сохранить несколько таблиц в один файл csv и затем открыть его?
Здравствуйте люди, помогите с проектом, нужно сохранить 2 таблицы в фаил csv через savedialog1, а затем также открыть данные csv через...

Нужно создать новый вектор и сохранить его в файл
Добрый день Нужно создать вектор, занести туда некоторые значения и сохранить их в файл. Вот, что я сделал vector &lt;string&gt;...

Необходимо изменить txt файл и сохранить его
Здравствуйте дорогие форумчане, нужна ваша помощь! Необходимо изменить txt файл и сохранить его. В файле следующий текст: &quot; Дорогие...

Как сохранить измененный файл в нужном формате
Нужно сохранить измененный файл Ексель формат которого файл Майкрософт Ексель, но получается только в формате Книга Ексель. Это одно и то...

Можно ли в уже откомпилированной программе открыть pas-файл, изменить его, сохранить и использовать дальше?
Добрый день) Такой вопрос Можно ли в уже откомпилированной программе открыть файл .pas его откоректировать сохранить и использовать дальше...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru