【问题标题】:Split text file Path to (x) number of files with VB.NET使用 VB.NET 拆分文本文件 (x) 个文件的路径
【发布时间】:2019-09-03 13:46:55
【问题描述】:

我在 stackoverflow.com 上到处搜索,但仍然没有解决方案:

我的代码很简单:

'Get Full Path of File
Dim elements As String = Path.GetTempPath() & "file.txt"
'Create A new folder for outputs if not exist
If (Not System.IO.Directory.Exists(Path.GetTempPath() & "folder")) Then
        System.IO.Directory.CreateDirectory(Path.GetTempPath() & "folder")
End If

我想将包含内容的 file.txt 划分为新文件夹中的 (x) 个文件

例子:

如果 x = 3

将自动创建输出文件:

/文件夹/file_1.txt

/文件夹/file_2.txt

/文件夹/file_3.txt

【问题讨论】:

  • 您想创建一个x 数量的相同文件,并使用变量作为进程的源来命名?空文件?是否还需要拆分原文件的内容
  • 不,原文件不为空,我想将文件中的内容分成多个文件
  • 分割原始文件内容的标准是什么?行数,也许(因为它是一个文本文件)?还有什么?
  • 主要是将内容分成多个文本文件
  • 基于什么逻辑?

标签: vb.net file split directory


【解决方案1】:
  1. 从现有文本文件中读取数据。
  2. 将数据分成任意数量的任意长度的字符串。
  3. 如果新目录不存在,请创建它。
  4. 在此目录中创建文件以存储任意数据部分,直到创建任意数量的文件并存储所有数据。

既然你拒绝提供逻辑(我想这是一个秘密),我将不得不做出一些假设。

  1. 原始文件包含长度大致相同的行。
  2. 目的是将原始文件分成大小大致相等的文件。
  3. 文件数量取决于原始文件的大小。

我根据行拆分文件,因此不会在 2 个文件之间拆分一个单词。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim OriginalFilePath = "C:/devlist.txt" '16KB file
    Dim lines = File.ReadAllLines(OriginalFilePath)
    Dim NumOfLines = lines.Length
    Dim NumOfFiles As Integer = GetNumberOfFiles(OriginalFilePath, NumOfLines)
    If NumOfFiles = -1 Then
        MessageBox.Show("No data in file.")
        Return
    End If
    'The "\" operator is integer division
    Dim LinesPerFile = NumOfLines \ NumOfFiles
    'Dim LeftoverLines = NumOfLines Mod NumOfFiles - didn't need this afterall
    Directory.CreateDirectory("C:\Some Directory")
    Dim StartIndex As Integer
    Dim EndIndex As Integer
    Dim sb As New StringBuilder
    For i = 0 To NumOfFiles - 1
        EndIndex = StartIndex + LinesPerFile
        If EndIndex >= NumOfLines - 1 Then
            EndIndex = NumOfLines - 1
        End If
        For index = StartIndex To EndIndex
            sb.AppendLine(lines(index))
        Next
        Dim NewFilePath = $"C:\Some Directory\SplitFile{i.ToString}.txt"
        '.WriteAllText will create the new file or overwrite it if it exists
        File.WriteAllText(NewFilePath, sb.ToString)
        StartIndex = EndIndex + 1
        sb.Clear()
    Next
End Sub

Private Function GetNumberOfFiles(FilePath As String, NumOfLines As Integer) As Integer
    Dim OriginalFileLength = New FileInfo(FilePath).Length
    Dim NumOfFiles As Integer
    Select Case OriginalFileLength
        Case 0
            MessageBox.Show("No data in file")
            Return -1
        Case 1
            NumOfFiles = 1
        Case 2
            If NumOfLines < 2 Then
                NumOfFiles = 1
            End If
            NumOfFiles = 2
        Case 3 To 10_000
            If NumOfLines < 3 Then
                NumOfFiles = NumOfLines
            Else
                NumOfFiles = 3
            End If
            'You can continue the If statements but I assumed
            'a file of this size would have at least 4 lines
        Case 10_001 To 100_000
            NumOfFiles = 4
        Case 100_001 To 500_000
            NumOfFiles = 5
        Case Else
            NumOfFiles = 6
    End Select
    Return NumOfFiles
End Function

16KB文件分割结果

【讨论】:

  • 可能剩下的可以插入到最后一个新文件中
  • @user11982798 所有数据都包含在四个文件之一中。最后一个文件可能比其他文件小。
  • 谢谢 Mary,但我在这行中有一些错误:Case 3 To 10_000 and Case 10_001 To 100_000 and Case 100_001 To 500_000
  • @AnassElFakir 抱歉出现错误。这可能取决于您使用的 Visual Studio 版本。我使用的是 2019,此版本允许下划线“_”字符作为数字中的分隔符,以使代码更易于阅读。尝试只删除下划线。 (10_001 到 10001)在任何带有下划线的数字上。
【解决方案2】:

这只是示例

    Dim Divider = 3
    Dim myNewFile(Divider - 1) As String
    Dim fileReader As String
    fileReader = My.Computer.FileSystem.ReadAllText("C:\test.txt")
    Dim myNewSize As Long = 0
    Long.TryParse(fileReader.Length / Divider, myNewSize)
    If myNewSize = 0 Then
        MessageBox.Show("Can't Be Processed")
        Exit Sub
    End If
    For myCnt As Int16 = 0 To divider - 1
        myNewFile(myCnt) = fileReader.Substring(myCnt * myNewSize + 1, myNewSize)
    Next

    'Resize The Last For Include The Remain
    Dim myNewLastSize As Long = myNewSize + fileReader.Length - myNewSize * Divider
    myNewFile(Divider - 1) = fileReader.Substring((Divider - 1) * myNewSize + 1, myNewLastSize)

然后你应该将每个拆分数据保存到每个它的表中

【讨论】:

  • 您为什么希望该部门返回一个 Long?请开启 Option Strict。这是一个两部分的过程。首先对于当前项目 - 在解决方案资源管理器中双击我的项目。选择左侧的编译。在 Option Strict 下拉列表中选择 ON。未来项目的第二个 - 转到工具菜单 -> 选项 -> 项目和解决方案 -> VB 默认值。在 Option Strict 下拉列表中选择 ON。这将使您避免在运行时出现错误。
  • 请不要在新代码中使用 Mid。尝试 .SubString 的 .net 版本
  • .TryParse 将字符串作为第一个参数。 fileReader.Length / Divider 不是字符串。
  • 为什么不在发帖前在 Visual Studio 中实际尝试一下答案。
  • 好的,谢谢你的评论,我可以得到任何知识,接下来我会尝试上网......但仍然需要提醒错误