Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 |

 

  Вопрос: Хранение списков Добавлено: 31.08.09 23:17  

Автор вопроса:  Winand | Web-сайт: winandfx.narod.ru
VB6. В коллекции объектов содержится информация о треках плейлиста. Мне нужен какой-то способ быстро сохранить эти данные хотя бы в виде строк (если уж скорее всего сериализации мне не видать). Допустим у меня в плеере два плейлиста по десять тыщ треков, как это быстро сохранить?
у каждого трека вот столько полей:
Public album As String
Public artist As String
Public comment As String
Public composer As String
Public copyright As String
Public genre As String
Public song As String
Public track As String
Public year As String
Public gotTags As Boolean 'После запроса тегов = true

Public file As String
Public tlen As Long 'Song length (s)
Public flen As Long 'File size
Public remote As Boolean

'Stream info
Public channels As Long
Public frequency As Long
Public ctype As Long
Public plugin As Long

Ответить

  Ответы Всего ответов: 17  

Номер ответа: 1
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #1 Добавлено: 01.09.09 07:47
имхо .. xml тут прям напрашивается.. Описываешь структуру трека и вперед.. делать ту же сериализацию только вручную..

Ответить

Номер ответа: 2
Автор ответа:
 Илья



Вопросов: 1
Ответов: 48
 Профиль | | #2 Добавлено: 01.09.09 15:58
  1. Public album As String
  2. Public artist As String
  3. Public comment As String
  4. Public composer As String
  5. Public copyright As String
  6. Public genre As String
  7. Public song As String
  8. Public track As String
  9. Public year As String
  10. Public gotTags As Boolean 'После запроса тегов = true
  11.  
  12. Public file As String
  13. Public tlen As Long 'Song length (s)
  14. Public flen As Long 'File size
  15. Public remote As Boolean
  16.  
  17. 'Stream info
  18. Public channels As Long
  19. Public frequency As Long
  20. Public ctype As Long
  21. Public plugin As Long


Winand, а не проще узнавать артиста, жанр и прочуюю информацию выдерая её из файла, а в список вносить путь к файлу, так и быстрее будет

Ответить

Номер ответа: 3
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #3
Добавлено: 01.09.09 19:12
Илья, file содержит путь к файлу.
Winamp же так не делает как ты предлагаешь, он один раз читает и запоминает, когда обращаешься к треку теги обновляем, читаем заново.

Ответить

Номер ответа: 4
Автор ответа:
 Илья



Вопросов: 1
Ответов: 48
 Профиль | | #4 Добавлено: 01.09.09 21:25
Winamp же так не делает как ты предлагаешь, он один раз читает и запоминает

А ты хочешь сделать второй винамп или что-то новое?

Вообще можно сделать линейное хранение:
  1. [2]
  2. path=...
  3. Album=...
  4. artist=...
  5. ...
  6. path=...
  7. Album=...
  8. artist=...
  9. ...

И в таком стиле продолжать заполнять значения в файл, такой файл легко прочитать, и именно так делает винамп, правда не совсем так, но алгоритм похож, если уж тебе нужно что-то подобное

Ответить

Номер ответа: 5
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #5
Добавлено: 01.09.09 22:13
В каком-то смысле второй винамп) Цель - удобный простой плеер под себя. При том не недоплеер, а настоящий юзабельный.

Ну что ж EROS, я ранее думал об XML, но не решался начать разбираться) Спасибо.
Плейлист в 5581 трек пишется в файл за 0.9-1.0 сек. Получаем xml размером 2.59Мб. Вполне разумно и терпимо вроде бы. Загрузку назад правда пока не делал.

Ответить

Номер ответа: 6
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #6
Добавлено: 02.09.09 02:55
С другой стороны в бинарный файл своего формата наверное еще быстрее записывать.
UPD. Чтение этих 5581 трека идет 20 секунд. Не катит вообще)
  1. ...
  2.     Set item = getFirstItemXml(subnode, node)
  3.     If Not item Is Nothing Then
  4.         Do
  5.             playlist.add item
  6.             PlList.AddItem item.file
  7.             updateListItem PlList.count - 1
  8.             Set item = getNextItemXml(subnode)
  9.             If item Is Nothing Then Exit Do
  10.         Loop
  11.     End If
  12. ...
  13.  
  14. Public Function getFirstItemXml(ByRef subnode As IXMLDOMNode, ByRef node As IXMLDOMNode) As playItem
  15.     Dim ssubnode As IXMLDOMNode
  16.     Set subnode = node.firstChild
  17.     If subnode Is Nothing Then Exit Function
  18.     Set ssubnode = subnode.firstChild
  19.     Set getFirstItemXml = New playItem
  20.     With getFirstItemXml
  21.     .album = ssubnode.Text
  22.     .artist = nextText(ssubnode)
  23.     .comment = nextText(ssubnode)
  24.     .composer = nextText(ssubnode)
  25.     .copyright = nextText(ssubnode)
  26.     .genre = nextText(ssubnode)
  27.     .song = nextText(ssubnode)
  28.     .track = nextText(ssubnode)
  29.     .year = nextText(ssubnode)
  30.     .gotTags = IIf(nextText(ssubnode) = "1", True, False)
  31.     .file = nextText(ssubnode)
  32.     .tlen = Val(nextText(ssubnode))
  33.     .flen = Val(nextText(ssubnode))
  34.     .remote = IIf(nextText(ssubnode) = "1", True, False)
  35.     .channels = Val(nextText(ssubnode))
  36.     .frequency = Val(nextText(ssubnode))
  37.     .ctype = Val(nextText(ssubnode))
  38.     .plugin = Val(nextText(ssubnode))
  39.     End With
  40. End Function
  41.  
  42. Public Function getNextItemXml(ByRef subnode As IXMLDOMNode) As playItem
  43.     Dim ssubnode As IXMLDOMNode
  44.     Set subnode = subnode.nextSibling
  45.     If subnode Is Nothing Then Exit Function
  46.     Set ssubnode = subnode.firstChild
  47.     Set getNextItemXml = New playItem
  48.     With getNextItemXml
  49.     .album = ssubnode.Text
  50.     .artist = nextText(ssubnode)
  51.     .comment = nextText(ssubnode)
  52.     .composer = nextText(ssubnode)
  53.     .copyright = nextText(ssubnode)
  54.     .genre = nextText(ssubnode)
  55.     .song = nextText(ssubnode)
  56.     .track = nextText(ssubnode)
  57.     .year = nextText(ssubnode)
  58.     .gotTags = IIf(nextText(ssubnode) = "1", True, False)
  59.     .file = nextText(ssubnode)
  60.     .tlen = Val(nextText(ssubnode))
  61.     .flen = Val(nextText(ssubnode))
  62.     .remote = IIf(nextText(ssubnode) = "1", True, False)
  63.     .channels = Val(nextText(ssubnode))
  64.     .frequency = Val(nextText(ssubnode))
  65.     .ctype = Val(nextText(ssubnode))
  66.     .plugin = Val(nextText(ssubnode))
  67.     End With
  68. End Function
  69.  
  70. Private Function nextText(ByRef node As IXMLDOMNode) As String
  71.     Set node = node.nextSibling
  72.     If Not node Is Nothing Then nextText = node.Text
  73. End Function

Ответить

Номер ответа: 7
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #7 Добавлено: 02.09.09 07:38
Чтение этих 5581 трека идет 20 секунд. Не катит вообще)

Ну что я могу сказать.. по всей видимости это кривая реализация библиотеки.. потому как на НЕТ на файлах до 50Мб разницы практически никакой.. будь то бинарная сериализация или xml. А при таком раскладе тебе однозначно надо на бинарник переходить. На больших файлах выигрыш в скорости будет достаточно серьезный..

Ответить

Номер ответа: 8
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #8 Добавлено: 02.09.09 22:36
При качественной реализации механизма на адеватных размерах данных разницы между бинарным форматом и XML практически не будет, потому что почти все время займут операции работы с диском

Ответить

Номер ответа: 9
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #9
Добавлено: 02.09.09 22:49
А если читать данные в переменную и парсить регэкспом? наверное всё таки не 20 секунд это будет

Ответить

Номер ответа: 10
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #10 Добавлено: 02.09.09 22:52
рэгексп это на самом деле не так быстро как хотелось бы того

Ответить

Номер ответа: 11
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #11
Добавлено: 02.09.09 23:34
Так, Венамп хранит в таком формате
#EXTM3U
#EXTINF:244,5'Nizza - Сюрная
F:\My Music\5'nizza\2003 - Пятница\01 - Сюрная.mp3
#EXTINF:166,5'Nizza - Я не той...
F:\My Music\5'nizza\2003 - Пятница\02 - Я не той....mp3
<...>

и запускается быстро. Хотя тут на каждый трек по 3 параметра, а не по 18)
Наверное и правда не нужно столько данных хранить постоянно.

Ответить

Номер ответа: 12
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #12
Добавлено: 04.09.09 04:03
Остановился на бинарном формате. Время парсинга файла(1026Кб) 1.3 сек. Правда на неправильном плейлисте сразу упало ide видимо из-за CopyMemory.

Ответить

Номер ответа: 13
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #13 Добавлено: 04.09.09 04:26
CopyMemory? О_О

1.3 сек - это с учетом считывания файла с диска или без?
Сколько времени занимает отдельно парсинг без IO?

Ответить

Номер ответа: 14
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #14
Добавлено: 04.09.09 18:46
чтение этого файла в массив байтов занимает 0 мс=) думаю без моего raid 0 все равно не было бы дольше
  1. Public Function ReadBytesFromFile(filename As String) As Byte()
  2. On Error GoTo ErrorHandler
  3.     Dim lHandle As Long
  4.     Dim lSuccess As Long
  5.     Dim lBytesRead As Long
  6.     Dim lBytesToRead As Long
  7.     Dim bytArr() As Byte
  8.     
  9.     
  10.     lBytesToRead = FileLen(filename)
  11.     ReDim bytArr(lBytesToRead) As Byte
  12.     'Get a handle to file
  13.     lHandle = CreateFile(filename, GENERIC_READ, _
  14.                          0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
  15.     If lHandle <> INVALID_HANDLE_VALUE Then
  16.         'read file contents into a bytearray and convert to string
  17.        lSuccess = ReadFile(lHandle, bytArr(0), _
  18.                            lBytesToRead, lBytesRead, 0)
  19.        
  20.       
  21.        ReadBytesFromFile = bytArr
  22.        CloseHandle lHandle
  23.        
  24.     End If
  25. ErrorHandler:
  26. End Function


По сути 1.3 сек это парсинг с добавлением объектов в коллекцию и эдементов listview
  1. ...    Do
  2.         playlist.add getItemFromFile(dat, pos)
  3.         PlList.AddItem ""
  4.         updateListItem PlList.count - 1 '&#206;&#225;&#237;&#238;&#226;&#235;&#255;&#229;&#236; &#239;&#238;&#235;&#255; &#242;&#224;&#225;&#235;&#232;&#246;&#251;
  5.     Loop While pos < ub
  6. ...
  7. Public Function getItemFromFile(ByRef dat() As Byte, ByRef pos As Long) As playItem
  8.     Dim lens(2) As Integer
  9.     Set getItemFromFile = New playItem
  10.     With getItemFromFile
  11.     .gotTags = dat(pos)
  12.     pos = pos + 1
  13.     .tlen = byteToLng(dat, pos)
  14.     pos = pos + 4
  15.     .flen = byteToLng(dat, pos)
  16.     pos = pos + 4
  17.     .remote = dat(pos)
  18.     pos = pos + 1
  19.     lens(0) = byteToInt(dat, pos)
  20.     pos = pos + 2
  21.     .artist = midFromArr(dat, pos, lens(0))
  22.     pos = pos + lens(0)
  23.     lens(1) = byteToInt(dat, pos)
  24.     pos = pos + 2
  25.     .song = midFromArr(dat, pos, lens(1))
  26.     pos = pos + lens(1)
  27.     lens(2) = byteToInt(dat, pos)
  28.     pos = pos + 2
  29.     .file = midFromArr(dat, pos, lens(2))
  30.     pos = pos + lens(2)
  31.     End With
  32. End Function
  33.  
  34. Public Function boolToByte(ByRef bool As Boolean) As Byte()
  35.     Dim arr(0) As Byte
  36.     If bool Then arr(0) = 1
  37.     boolToByte = arr
  38. End Function
  39.  
  40. 'Read lng from pos in byte array
  41. Public Function lngToByte(ByRef lng As Long) As Byte()
  42.     Dim arr(3) As Byte
  43.     CopyMemory arr(0), ByVal VarPtr(lng), 4
  44.     lngToByte = arr
  45. End Function
  46.  
  47. 'Read lng from pos in byte array
  48. Public Function byteToLng(ByRef lng() As Byte, ByVal pos As Long) As Long
  49.     CopyMemory ByVal VarPtr(byteToLng), lng(pos), 4
  50. End Function
  51.  
  52. 'Write byte array to pos in byte array
  53. Public Sub copyToArr(ByRef arrTo() As Byte, ByRef arrFrom() As Byte, ByVal pos As Long)
  54.     CopyMemory arrTo(pos), arrFrom(0), UBound(arrFrom) + 1
  55. End Sub
  56.  
  57. 'Mid byte array from byte array
  58. Public Function midFromArr(ByRef arrFrom() As Byte, ByVal pos As Long, ByVal bytes As Long) As Byte()
  59. If bytes = 0 Then Exit Function
  60.     Dim arrTo() As Byte
  61.     ReDim arrTo(bytes)
  62.     CopyMemory arrTo(0), arrFrom(pos), bytes
  63.     midFromArr = arrTo
  64. End Function
  65.  
  66. 'Write str to pos in byte array
  67. Public Sub strToArr(ByRef arrTo() As Byte, ByRef str As String, ByVal pos As Long)
  68.     CopyMemory arrTo(pos), ByVal StrPtr(str), LenB(str)
  69. End Sub
  70.  
  71. 'Write int to pos in byte array
  72. Public Sub intToArr(ByRef arrTo() As Byte, ByRef intg As Integer, ByVal pos As Long)
  73.     CopyMemory arrTo(pos), ByVal VarPtr(intg), 2
  74. End Sub
  75.  
  76. 'Read int from pos in byte array
  77. Public Function byteToInt(ByRef intg() As Byte, ByVal pos As Long) As Integer
  78.     CopyMemory ByVal VarPtr(byteToInt), intg(pos), 2
  79. End Function
  80.  
  81. 'Write lng to pos in byte array
  82. Public Sub lngToArr(ByRef arrTo() As Byte, ByRef lng As Long, ByVal pos As Long)
  83.     CopyMemory arrTo(pos), ByVal VarPtr(lng), 4
  84. End Sub

Ответить

Номер ответа: 15
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #15 Добавлено: 05.09.09 01:41
0 мс - это не чтение с RAID0, а чтение из кеш-памяти.

Может меня .NET сильно разбаловал, но для анализа бинарного файла и его загрузки в ListBox 1.3 с - это слишком много...

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам