Загрузите файл Visual Basic в строку (,), разделенную вкладками - PullRequest
0 голосов
/ 02 июля 2018

У меня есть несколько файлов разных размеров. Но я хочу сделать то же самое со всеми из них, загрузить их в строку (,).

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

    Dim strimport As String() = {}
    Dim strimportsplit As String(,) = {}
    Dim i As Integer = 0

    strimport = File.ReadAllLines("C:\test.txt")

    For i = 0 To strimport.Length - 1
        strimportsplit = strimport(i).Split(New Char() {vbTab}) 'This line doesn't work
    Next

Это пример моих файлов (только они значительно больше):

aaa fff 0
bbb ggg 1
ccc hhh 2
ddd iii 3
eee jjj 4

Вот как я бы хотел, чтобы вышеперечисленное загружалось в мой массив из внешних текстовых файлов:

        Dim strexample As String(,) = {{"aaa", "fff", "0"},
                                {"bbb", "ggg", "1"},
                                {"ccc", "hhh", "2"},
                                {"ddd", "iii", "3"},
                                {"eee", "jjj", "4"}}

Я даже пытался добавить все свои таблицы как строки (,) в VB вручную. Это работает ... Но при ручном вводе размер файла увеличивается до ~ 30 МБ и дает мне ОГРОМНЫЙ удар по производительности. Не очень идеально.

У меня вопрос, как я могу загрузить из текстового файла строку (,), аналогичную моему последнему примеру выше?

Большое спасибо заранее.

Ответы [ 3 ]

0 голосов
/ 02 июля 2018
strimportsplit = strimport(i).Split(New Char() {vbTab}) 'This line doesn't work

Это не работает, потому что вы каждый раз меняете значение strimportsplit. Вы не добавляете к нему больше «строк», как, по вашему мнению, происходит.

Если вы действительно хотите использовать двумерный массив, вам нужно знать длину для обоих измерений, или вам нужно будет выполнить некоторые преобразования позже. Вы можете рассчитать длину и создать 2D-массив, выполнив что-то вроде этого:

Dim lines As String() = File.ReadAllLines(filePath)
Dim height As Integer = lines.Count - 1
' Calculating the max. number of "columns" in case they vary.
Dim width As Integer = lines.Select(Function(l) l.Split(vbTab).Count).Max - 1

Dim my2DArray(height, width) As String

For i = 0 To lines.Count - 1
    Dim columns As String() = lines(i).Split(vbTab)
    For j = 0 To columns.Count - 1
        my2DArray(i, j) = columns(j)
    Next
Next

Обратите внимание, что если строки не имеют одинаковое количество «столбцов», некоторые элементы в массиве будут равны нулю (или Nothing).

Однако, гораздо лучший способ - использовать зубчатый массив вместо 2D-массива. Вы можете достичь этого, используя Linq, написав что-то простое:

Dim myJaggedArray As String()() = File.ReadAllLines(filePath).
                                       Select(Function(l) l.Split(vbTab)).ToArray

Зубчатый массив - это массив массива (массив строкового массива в вашем случае), к которому вы можете обращаться к его значениям, используя arr(x)(y) вместо arr(x, y).


Другой альтернативой для решения этой ситуации является использование любой существующей библиотеки, которая работает с файлами с разделителями (через запятую, через табуляцию и т. Д.) Вместо того, чтобы обрабатывать это самостоятельно. Я бы рекомендовал использовать GenericParser , который вы можете легко использовать для загрузки данных из файлов с разделителями в DataTable. Вы можете проверить мой ответ на другой вопрос , чтобы узнать больше о том, как его использовать.

0 голосов
/ 02 июля 2018

Вместо использования зубчатого массива я бы использовал List of String (). Вот ваш код, слегка модифицированный для иллюстрации.

    Dim strimport() As String

    strimport = IO.File.ReadAllLines("C:\test.txt")

    Dim StrImportSplit As New List(Of String())

    For Each ln As String In strimport 'iterate lines in file
        StrImportSplit.Add(ln.Split(New Char() {ControlChars.Tab}))
    Next

И чек

    'check
    For lidx As Integer = 0 To StrImportSplit.Count - 1 'rows
        Dim l As New System.Text.StringBuilder
        For cidx As Integer = 0 To StrImportSplit(lidx).Length - 1 'columns
            l.Append(StrImportSplit(lidx)(cidx))
            l.Append(" ")
        Next
        Debug.WriteLine(l)
    Next
0 голосов
/ 02 июля 2018

Это было бы проще, если бы вы переключились на Jagged Array вместо двумерного. Проблема (здесь) с двумерными массивами заключается в том, что вы можете получить доступ и изменить только один элемент за раз, тогда как с помощью зубчатого массива вы можете получить доступ к всей строке .

Зубчатый массив по сути массив массивов и может быть объявлен как:

Dim strimportsplit As String()()

Вы должны установить размер строки равный strimport.Length, чтобы гарантировать, что он может содержать одинаковое количество строк:

Dim strimport As String()
Dim strimportsplit As String()()

'Dim i As Integer = 0 -- No need for this, it's declared by the loop.

strimport = File.ReadAllLines("C:\test.txt")
strimportsplit = New String(strimport.Length - 1)() {}

ПРИМЕЧАНИЕ: Причина, по которой я использую strimport.Length - 1 выше, заключается в том, что в VB.NET вы на самом деле не указываете длину при объявлении нового массива , а точнее индекс последнего элемента . И поскольку индексы начинаются с 0, последний элемент будет иметь индекс Length - 1.

Затем внутри цикла вы просто используете i для ссылки на текущий массив (строку / строку) элементов:

strimportsplit(i) = strimport(i).Split(New Char() {vbTab})

Доступ к предмету можно сделать так:

'strimportsplit(row)(column)

MessageBox.Show(strimportsplit(0)(1)) 'Displays "fff".
MessageBox.Show(strimportsplit(3)(2)) 'Displays "3".

Вы также можете получить доступ ко всей строке, если хотите:

Dim ThirdRow As String() = strimportsplit(2)

MessageBox.Show(ThirdRow(0)) 'Displays "ccc".
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...