Получение дополнительных шестнадцатеричных байтов при объединении файлов данных - PullRequest
0 голосов
/ 08 августа 2009

Я объединяю файлы данных, но проблема в том, что я вижу дополнительные байты, где файлы объединяются. Новый файл имеет дополнительные байты. Я думал, что это может быть проблема с кодировкой.

Вот методы, которые я пытался использовать для объединения файлов. В первом примере я получаю дополнительные 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 ]

2 голосов
/ 08 августа 2009

0xA0 0x00 - символ перевода строки UTF-16. Первый фрагмент кода использует UTF-16 (кодировка .NET по умолчанию, используемая для строк), а второй ASCII.

В вашем первом фрагменте кода BinaryWriter поддерживает запись строк в определенной кодировке.

BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII);
0 голосов
/ 11 августа 2009

Байты оказались в конце каждого файла ....

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

Поскольку я получал два дополнительных байта каждый раз, когда добавлял файл, я вычитал 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
0 голосов
/ 08 августа 2009

Почему вы вообще используете 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

Вызовите это несколько раз, по одному на каждый входной файл, но каждый раз с одним и тем же потоком вывода. (Очевидно, не закрывайте его между вызовами.)

0 голосов
/ 08 августа 2009

Здесь просто выстрел в темноте, но если эти файлы на самом деле кодируются как UTF-8/16/32 (а не ASCII), вы можете увидеть UTF BOM ( Byte Order Mark ) между им.

Попробуйте изменить кодировку на UTF-8, и, если это текст, укажите кодировку при чтении.

ПРИМЕЧАНИЕ. UTF-8 - это расширенный набор ASCII, так что в любом случае это был бы лучший способ их прочитать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...