2013-04-11 8 views
1

Я использую .Net framework для разработки приложения, которое взаимодействует с смарт-картой Gemalto (добавление и извлечение), Я последовательно делал с добавочной частью, однако, когда я пытаюсь прочитать данные, которые я сохранил на карточке, я получил outOfMemoryException в хост-приложении, может ли кто-нибудь понять, почему это происходит?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(); 
} 
+0

может кто-нибудь помочь ??? – user1477701

+0

что вы пытаетесь достичь? как сделать этот массив/List BookList и как вы заполняете данные в эту коллекцию? –

ответ

1

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

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

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

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

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

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

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

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

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

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

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

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

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

Я бы не заподозрил, что энергонезависимая память закончилась, поскольку оригинальная публикация утверждает, что ошибка возникает во время чтения. – guidot

+0

На самом деле обе памяти имеют ограничения, после проверки проблемы чтения из-за того, что он читает более энергозависимую память, может хранить 16 КБ. –

0

Вы пытаетесь задача, не типичная для смарт-карт. Обратите внимание: эти карты имеют оперативную память в диапазоне от нескольких kByte, которые должны быть разделены между операционной системой и буфером ввода-вывода. Последнее вряд ли превысит 2 kByte (см. Руководство по карте для этого), и даже тогда вам нужно использовать APDU с расширенной длиной, как указано в this answer. Поэтому вероятной причиной вашей ошибки является то, что длина данных превышает объем ОЗУ для буфера ввода-вывода. Хотя расширение буфера или использование расширенных APDU будет растягивать предел, все равно легко ударить его с действительно длинным описанием.

+0

Большое спасибо за ваш ответ, поэтому вы имели в виду, что ограниченная оперативная память вызывает эту проблему, и подходящим решением в этом случае является расширение буфера или использование расширенного APDU, но как выполнить это решение на .Net-смарт-карте? – user1477701

+0

@ user1477701; право, расширение буфера, к сожалению, является проприетарной операцией, так как семейство ISO 7816 не указывает на нее никакой команды, поэтому вам нужно посмотреть руководство по карте. В разделе расширенной длины этот Q/A http://www.codeproject.com/Messages/4413993/Extended-Length-APDU.aspx предполагает, что он недоступен из коробки в .net. – guidot

0

Я получил это исключение только при попытке получить длинную строку (например, не более 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++; 
} 
+0

см. Обновленный ответ –

+0

Большое спасибо Mr. Wajdy Essam, на самом деле я получил это исключение, пытаясь прочитать с карты не при попытке добавить. Эти длинные строки успешно сохраняются на моей карте, но я не могу их прочитать. Я уверен в этом, потому что, когда я пытаюсь получить только BookID только что добавленной книги, у которой есть длинное описание, я могу прочитать этот идентификатор успешно. – user1477701

+0

Спасибо Mr.Wajdy, компрессия решает мою проблему, и пока это работает очень хорошо со мной .. – user1477701