ASP NET, NET Framework, MONO, SQL, Visual Studio | Professional Programs | Программист Еремин В.В.
(SOFT) SOFT (2011 год)

CSV_Spliter - разрезка больших CSV-файлов

Я несколько лет работал в электронном магазине http://digitalshop.ru/ и занимался там наполнением контента магазина с помощью пауков, приведением прайсов в единый формат и многими-многими подобными операциями по формированию базы магазина. Здесь я опубликую одну свою старинную утилитку из 2005-го года для работы с БОЛЬШИМИ прайс-листами. Столь большими, что их не получается откруть для редактирования или загрузить через WEB.

Эта утилита корректно разрезает большой прайс-лист на несколько маленьких.


Код никаких хитростей не имеет - он перед вами. В текущей версии я внес несколько модификаций и переделал обычную сортировку массива на сортировку с помощью LINQ (строка 137).


   1:  Module Module1
   2:   
   3:      Sub Main()
   4:          Dim PRM() As String = Environment.GetCommandLineArgs
   5:          Dim Num As Integer = 2
   6:          Dim Encode1 As System.Text.Encoding = Text.Encoding.GetEncoding(1251)
   7:          Try
   8:              For Each One As String In PRM
   9:                  'оттобрали в параметрах хелп
  10:                  If One.ToLower.Contains("-help") Or One.ToLower.Contains("/help") Or One.ToLower.Contains("/h") Or One.ToLower.Contains("-h") Then
  11:                      Console.WriteLine("ParseParm: Help request.")
  12:                      GoTo Usage
  13:                  End If
  14:              Next
  15:              For Each One As String In PRM
  16:   
  17:                  If One.StartsWith("-") Then
  18:                      If IsNumeric(One.Replace("-", "").Trim) Then
  19:                          'отобрали на сколько частей разбиваем CSV файл
  20:                          Num = CInt(One.Replace("-", "").Trim)
  21:                      Else
  22:                          'кодировка входного и выходного файла
  23:                          Select Case One.ToLower
  24:                              Case "ascii"
  25:                                  Encode1 = Text.Encoding.GetEncoding(1251)
  26:                              Case "utf8"
  27:                                  Encode1 = Text.Encoding.UTF8
  28:                              Case "unicode"
  29:                                  Encode1 = Text.Encoding.Unicode
  30:                              Case Else
  31:                                  Console.WriteLine("ParseParm: Encode not parse.")
  32:                                  GoTo Usage
  33:                          End Select
  34:                      End If
  35:                  End If
  36:              Next
  37:              'выясним имя рабочего файла 
  38:              Dim FullFileName As String = ""
  39:              For Each One As String In PRM
  40:                  If Not One.StartsWith("-") Then
  41:                      If Not One.ToLower.Contains("csv_spliter") And Not One.ToLower.Contains("exe") Then
  42:                          If Not GetWorkFile(One, FullFileName) Then
  43:                              Console.WriteLine("ParseParm: Default filename.")
  44:                              GoTo Usage
  45:                          Else
  46:                              'имя задано в параметрах - его вернул GetWorkFile
  47:                              GoTo SetFile
  48:                          End If
  49:                      End If
  50:                  End If
  51:              Next
  52:              'имя не задано - рабочий каталог по умолчанию
  53:              If Not GetWorkFile(My.Application.Info.DirectoryPath, FullFileName) Then
  54:                  Console.WriteLine("WorkFile :" & FullFileName)
  55:                  GoTo Usage
  56:              End If
  57:  SetFile:
  58:              If My.Computer.FileSystem.FileExists(FullFileName) Then
  59:                  Console.WriteLine("Spliting " & FullFileName & " (" & Encode1.ToString.Replace("System.Text.", "") & ") " & " on " & Num & " slice. ")
  60:                  Console.WriteLine("Please wait...")
  61:              Else
  62:                  Console.WriteLine("WorkFile :" & FullFileName & " not found.")
  63:                  GoTo Usage
  64:              End If
  65:              '
  66:              'есть входной файл и все параметры
  67:              '
  68:              Dim AllData As String = My.Computer.FileSystem.ReadAllText(FullFileName, Encode1)
  69:              Dim RDR1 As New IO.StringReader(AllData)
  70:              Dim Head As String = RDR1.ReadLine()
  71:              Dim Str1 As String = ""
  72:              Dim LineCount As Integer = 0
  73:              'не более 100 миллионов строк
  74:              For i As Integer = 1 To 100000000
  75:                  Str1 = RDR1.ReadLine
  76:                  If Str1 Is Nothing Then
  77:                      Exit For
  78:                  Else
  79:                      'в первом проходе посчитаем количество строк
  80:                      LineCount += 1
  81:                  End If
  82:              Next
  83:              RDR1.Close()
  84:              'теперь основной проход с копированием
  85:              Dim RDR2 As New IO.StringReader(AllData)
  86:              RDR2.ReadLine()
  87:              Dim LineInSlice As Integer = LineCount \ Num
  88:              Dim NewFileName As String = ""
  89:              Dim LineNumber As Integer = 2
  90:              Dim StartLineNumber As Integer = 0
  91:              For SliceNum As Integer = 1 To Num
  92:                  If SliceNum = Num Then
  93:                      'последний слайс до конца
  94:                      StartLineNumber = LineNumber
  95:                      Dim Out2 As New Text.StringBuilder()
  96:                      Out2.AppendLine(Head)
  97:                      For i As Integer = 1 To LineCount
  98:                          Dim CurLine As String = ""
  99:                          LineNumber += 1
 100:                          CurLine = RDR2.ReadLine
 101:                          If CurLine Is Nothing Then Exit For
 102:                          Out2.AppendLine(CurLine)
 103:                      Next
 104:                      NewFileName = FullFileName.Replace(".csv", "-" & SliceNum & ".csv")
 105:                      My.Computer.FileSystem.WriteAllText(NewFileName, Out2.ToString, False, Encode1)
 106:                      Console.WriteLine("Write " & NewFileName & ", Line " & StartLineNumber & "-" & LineNumber - 1)
 107:                  Else
 108:                      StartLineNumber = LineNumber
 109:                      Dim Out1 As New Text.StringBuilder()
 110:                      Out1.AppendLine(Head)
 111:                      For i As Integer = 0 To LineInSlice
 112:                          LineNumber += 1
 113:                          Out1.AppendLine(RDR2.ReadLine)
 114:                      Next
 115:                      NewFileName = FullFileName.Replace(".csv", "-" & SliceNum & ".csv")
 116:                      My.Computer.FileSystem.WriteAllText(NewFileName, Out1.ToString, False, Encode1)
 117:                      Console.WriteLine("Write " & NewFileName & ", Line " & StartLineNumber & "-" & LineNumber - 1)
 118:                  End If
 119:              Next
 120:              RDR2.Close()
 121:              Exit Sub
 122:   
 123:          Catch ex As Exception
 124:              Console.WriteLine("Error: " & ex.Message)
 125:              Console.ReadLine()
 126:              GoTo Usage
 127:          End Try
 128:  Usage:
 129:          Console.WriteLine(PRM.Count.ToString & ", " & My.Application.Info.DirectoryPath)
 130:          Console.WriteLine("Usage:    CSV_Spliter.exe [-Num] [-ACSII/Unicode/UTF8] [FileName/DirectoryName] [/help] [-help] [/h] [-h]" & vbCrLf & _
 131:                            "          This program splitting large CSV file " & vbCrLf & _
 132:                            "Num:      Number on CSV segment, default 2" & vbCrLf & _
 133:                            "Encode:   ACSII or Unicode or UTF8 - input and output CSV encoding, default codepage 1251" & vbCrLf & _
 134:                            "FileName: Defaul last creating file in working directory.")
 135:   
 136:          Exit Sub
 137:      End Sub
 138:   
 139:      Function GetWorkFile(ByVal Parm As String, ByRef FullFileName As String) As Boolean
 140:          Try
 141:              If IO.Path.GetExtension(Parm) = "" Then
 142:                  'задан только каталог - ищем последний созданный CSV-Файл   
 143:                  Dim WorkDir As IO.DirectoryInfo = My.Computer.FileSystem.GetDirectoryInfo(Parm)
 144:                  If WorkDir.GetFiles("*.csv").Count = 0 Then
 145:                      Console.WriteLine("GetWorkFile: No *.csv files in direcory " & Parm)
 146:                      FullFileName = ""
 147:                      Return False
 148:                  Else
 149:                      Dim FileList() As IO.FileInfo = WorkDir.GetFiles("*.csv")
 150:                      Dim OrderedList = (From X In FileList Select X Where X.Extension.ToLower = ".csv" Order By X.CreationTime Descending).First
 151:                      Dim LastCSV As String = OrderedList.Name
 152:                      FullFileName = IO.Path.Combine(Parm, LastCSV)
 153:                      Return True
 154:                  End If
 155:              ElseIf IO.Path.GetExtension(Parm).ToLower = ".csv" Then
 156:                  'задан CSV -файл
 157:                  If IO.Path.GetDirectoryName(Parm) = "" Then
 158:                      'задано только имя файла
 159:                      FullFileName = IO.Path.Combine(My.Application.Info.DirectoryPath, Parm)
 160:                      Return True
 161:                  Else
 162:                      'задано полное имя - диретория+файл
 163:                      FullFileName = Parm
 164:                      Return True
 165:                  End If
 166:              Else
 167:                  'расширение файла есть, но не CSV
 168:                  Console.WriteLine("GetWorkFile: Extensions " & IO.Path.GetExtension(Parm).ToLower)
 169:                  FullFileName = ""
 170:                  Return False
 171:              End If
 172:   
 173:          Catch ex As Exception
 174:              Console.WriteLine("Error in GetWorkFile: " & ex.Message)
 175:              Console.ReadLine()
 176:              FullFileName = ""
 177:              Return False
 178:          End Try
 179:   
 180:      End Function
 181:   
 182:  End Module

Сгрузить утилиту CSV_Spliter в откомпилированном виде можно отсюда.



Комментарии к этой страничке ( )
ссылка на эту страничку: http://www.vb-net.ru/CSV_Spliter/index.htm
<На главную>  <В раздел ASP>  <В раздел NET>  <В раздел SQL>  <В раздел Разное>  <Написать автору>  < Поблагодарить>