连接数据文件时获取额外的HEX字节

时间:2009-08-08 17:09:51

标签: .net vb.net file

我正在连接数据文件,但问题是我看到了文件加入的额外字节。新文件有额外的字节。我原以为这可能是编码问题。

以下是我尝试用来连接文件的方法。第一个例子我得到额外的0xA0 0x00字节。

     Dim inputfiles() As String = Directory.GetFiles(sourcedir, pattern)

     Dim bufSize As Integer = 1024 * 64
     Dim buf As Byte() = New Byte(bufSize) {}

     For Each inputfile As String In inputfiles

             Using fs As New FileStream(inputfile, FileMode.Open, FileAccess.Read)
                 Dim arrfile() As Byte = New Byte(fs.Length) {}
                 fs.Read(arrfile, 0, arrfile.Length)
                 fs.Close()

                 Using fo As New FileStream(outfilename, FileMode.Append, FileAccess.Write)
                     Using bw As New BinaryWriter(fo)
                         bw.Write(arrfile, 0, arrfile.Length)
                         bw.Close()
                         fo.Close()
                     End Using
                 End Using

             End Using
         Next

第二个我只得到0xA0字节。

     For Each inputfile As String In inputfiles
            Using fs As New FileStream(inputfile, FileMode.Open, FileAccess.Read)
                Using sr As New StreamReader(fs, Encoding.ASCII)
                    While Not sr.EndOfStream
                       Using fo As New FileStream(outfilename, FileMode.Append, FileAccess.Write)
                            Using sw As New StreamWriter(fo, Encoding.ASCII)
                                sw.Write(sr.ReadToEnd)
                                sw.Close()
                                fo.Close()
                            End Using
                        End Using
                    End While
                End Using
            End Using
       Next

感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

0xA0 0x00是UTF-16换行符。第一个代码段使用UTF-16(用于字符串的默认.NET编码)和第二个ASCII。

在您的第一个代码段中,BinaryWriter支持以特定编码写入字符串。

BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII);

答案 1 :(得分:0)

只是在黑暗中拍摄,但如果这些文件实际编码为UTF-8/16/32(而不是ASCII),您可能会看到它们之间的UTF BOM(Byte Order Mark)。

尝试将您的编码更改为UTF-8,如果它们是文本,则在阅读时为其提供编码。

注意UTF-8是一套超级ASCII,因此无论如何它都是更好的阅读方式。

答案 2 :(得分:0)

你为什么要使用BinaryWriter?您可以直接写入流。

一些一般性意见:

  • 如果您使用Using语句
  • ,则无需显式关闭流等
  • 如果您要复制二进制文件,那么您绝对 希望将它们视为文本。远离TextReader / TextWriters
  • 当您复制流时,通常应该循环读取一个块并将其写出来,记下Stream.Read的结果。这意味着你最终不会依赖:
    • 文件长度保持不变
    • 一次性阅读所有数据
    • 有足够的内存可以在一开始就一目了然地阅读
  • 为什么要多次重新打开输出流?只需打开一次并继续写信。
  • 您究竟如何确定输入和输出文件的内容?你使用的是十六进制编辑器吗?我想知道“额外”字节是否实际存在于输入文件中,但如果您使用文本编辑器查看文件,则只是没有注意到它们。

这是我觉得有用的方法的VB版本:

Public Shared Sub CopyStream(ByVal input As Stream, ByVal output As Stream)
    Dim num As Integer
    Dim buffer As Byte() = New Byte(&H2000  - 1) {}
    Do While (num = input.Read(buffer, 0, buffer.Length) > 0)
        output.Write(buffer, 0, num)
    Loop
End Sub

多次调用,每个输入文件一次,但每次都有相同的输出流。 (显然,不要在通话之间关闭它。)

答案 3 :(得分:0)

字节最终位于每个文件的末尾....

这可能是一个黑客,但这就是我在这里提出的解决方案。

因为每次添加文件时我都会得到两个额外的字节,所以我从新字节数组的长度中减去了2个。

Private Sub ConcatFiles(ByVal sourcedir As String, ByVal outfilename As String, ByVal pattern As String)

    Dim inputfiles() As String = Directory.GetFiles(sourcedir, pattern)
    Dim bufSize As Integer = 1024 * 64
    Dim buf As Byte() = New Byte(bufSize) {}

        Using fo As New FileStream(outfilename, FileMode.Append, FileAccess.Write)

            For Each inputfile As String In inputfiles

                Using fs As New FileStream(inputfile, FileMode.Open, FileAccess.Read)
                    Dim arrfile() As Byte = New Byte(fs.Length - 2) {}
                    fs.Read(arrfile, 0, arrfile.Length)
                    fo.Write(arrfile, 0, arrfile.Length)
                End Using

            Next

    End Using

End Sub