Исключение из памяти при чтении со смарт-карты

Я использую.Net Framework для разработки приложения, которое взаимодействует со смарт-картой Gemalto (добавление и получение), я успешно завершил добавочную часть, однако, когда я пытаюсь прочитать данные, хранящиеся на карте, я получил outOfMemoryException в хост-приложении, кто-нибудь может выяснить, почему это происходит?

это код в главном приложении, который читает с карты:

for (int i = 0; i < 5; i++)
{
     try
     {
          string bookString = service.getBook(i);
     }catch (Exception x) { 
          MessageBox.Show("an error occur");
     }
}

и в приложении, которое загружается на карту, у меня есть этот метод:

public string getBook(int index) 
{
     return BookList[index].getBookID() + " , " + BookList[index].getBookDesc();
}

3 ответа

Решение

Карта Gemalto .NET содержит как постоянную память, так и энергозависимую память, используемую для хранения данных. Постоянная память действует как постоянное хранилище для карты - данные сохраняются в ней даже после извлечения карты из устройства чтения смарт-карт. Энергозависимая память сбрасывается, когда карта теряет питание и не может использоваться для постоянного хранения.

как вы храните свои данные, и как вы заполняете данные BookList? пожалуйста, уточните больше.

Конечно, у вас есть ограничение памяти, поэтому вы не можете хранить до определенного размера, на этой.net-карте у вас есть 16 КБ энергозависимой памяти (ОЗУ) и 70 КБ постоянной памяти (которая содержит сборки, память для хранения).

Я протестировал некоторые карты Gemalto .net и смог хранить 20 КБ данных в постоянной памяти, после этого ограничения я получаю то же исключение OutOfMemoryException (поскольку остальные 50 КБ заполнены файлами, сборками).

Эта карта не предназначена для хранения базы данных, записей и т. Д. Она используется для хранения важной информации, такой как ключи и пароли. Так что не сохраняйте больше, чем этот размер, и ваш код будет в порядке, или используйте любой алгоритм сжатия текста (в клиентском приложении), чтобы уменьшить размер перед хранением на карте, но в конце не пытайтесь сохранить больше, чем это ~XX кб.

обновление: Из-за этого ограничения вы не можете хранить более 70 КБ в постоянном хранилище, также вы не можете извлечь более 16 КБ с карты на клиент (поскольку эти данные будут храниться в локальной переменной, то есть в энергозависимой памяти, а затем возвращаться обратно вашему клиенту, и у вас есть ограничения также здесь).

Так что это источник вашей проблемы, вы извлекаете больше, чем может содержать энергозависимая память:

public string getBook(int index)
{
  return bookList[index].getId() + " , " + bookList[index].getName();
}

перед возвращаемым значением эти данные будут временно переменными, и поскольку вы не можете хранить больше 16 КБ, вы получаете исключение OutOfMemoryException.

решение состоит в том, чтобы использовать это хранилище непосредственно от клиента (у вас есть ссылка, так что просто используйте его):

public Book getTheBook(int index)
{
   return bookList[index];
}

и из клиента вы можете получить доступ к функциональности Book (убедитесь, что ваша Book является struct, потому что marshalling поддерживается только для структур и примитивных типов в Gemalto .net card):

Console.WriteLine(service.getTheBook(0).getName());

Вы пытаетесь выполнить задачу, не типичную для смарт-карт. Обратите внимание, что карты имеют оперативную память в диапазоне нескольких килобайт, которые должны быть разделены между операционной системой и буфером ввода-вывода. Последнее вряд ли превысит 2 кБайт (для этого обратитесь к руководству по карте), и даже в этом случае вам необходимо использовать APDU увеличенной длины, как указано в этом ответе. Таким образом, вероятная причина вашей ошибки в том, что длина данных превышает объем оперативной памяти для буфера ввода-вывода. Несмотря на то, что увеличение буфера или использование расширенных APDU приведет к расширению предела, по-прежнему легко найти его с действительно длинным описанием.

Я получил это исключение только при попытке получить длинную строку (например, 100 слов). Я закончил с добавлением части, и это было сделано, просто отправив строку BookDesc.

public Book[] BookList=new Book[5];
public static int noOfBooks=0;

public string addBook(string bookDesc) 
{
   Book newBook=new Book();
   newBook.setBookDesc(bookDesc); 
   newBook.setBookID(noOfBooks);        
   BookList[noOfBooks]=newBook;
   noOfBooks++;
}
Другие вопросы по тегам