Разделить данные и собрать их вместе - PullRequest
1 голос
/ 19 ноября 2011

Это больше для практики, чем что-либо, на самом деле.У меня больше всего разочаровывает время, потому что это довольно новая концепция для меня.Я опубликую свой код ниже.

Что я пытаюсь сделать:

  1. Чтение файла в байтовый массив
  2. Разделение байта на пар предопределенногоразмер
  3. Соберите части вместе и запишите файл в HD

    byte [] sData = File.ReadAllBytes (@ "C: \ Project1.exe");// 16384 байта

    // Split the data up here
                    int range = 8;
                    range *= 1024;
                    int pos = 0;
                    int remaining;
                    int i = 0;
                    byte[] test = null;
                    while ((remaining = sData.Length - pos) > 0)
                    {
                        byte[] block = new byte[Math.Min(remaining, range)];
                        test = new byte[block.Length + pos];
                        Array.Copy(sData, pos, test, pos, block.Length);
                        pos += block.Length;
                        i++;
                    }
    
                    File.WriteAllBytes(@"C:\blank.exe", test);
    

Файл blank.exe всегда поврежден.

Кто-нибудь видит мои ошибки здесь?

Я ценю это, Эван

Ответы [ 3 ]

1 голос
/ 19 ноября 2011

Вы воссоздаете тестовый массив при каждом прохождении цикла.

Это означает, что когда вы записываете тестовый массив в файл в конце, вы записываете только последний блок данных, который вы обработали.

У вас есть несколько вариантов:

1) Измените размер массива на каждом проходе и скопируйте предыдущие данные в новый массив. Это было бы очень неэффективно. Это тот же механизм, который использует Array.Resize.

2) Если вы заранее знаете желаемый размер массива (т. Е. Он совпадает с размером данных, которые вы читаете из файла, или кратным размеру файла), просто измените размер массива один раз перед вводом петля.

3) Используйте другую структуру данных, такую ​​как List или ArrayList.

0 голосов
/ 19 ноября 2011

Может быть, я что-то упускаю, но вы впрыгиваете во весь файл заранее, так что вы уже не знаете, насколько большим должен быть выходной буфер.Ergo, с этим все в порядке:

private static void better_copy( ushort blockSize )
{
  if ( blockSize < 1 )  throw new ArgumentOutOfRangeException("blockSize") ;

  byte[] input  = File.ReadAllBytes( @"C:\Project1.exe" );   // 16,384 bytes
  byte[] output = new byte[ input.Length] ;

  for ( int p = 0 , n = 0 ; p < input.Length ; p += n )
  {
    int octetsRemaining = input.Length - p ;

    n = ( octetsRemaining < blockSize ? octetsRemaining : blockSize ) ;

    Array.Copy( input , p , output , p , n ) ;

  }

  File.WriteAllBytes( @"C:\blank.exe" , output );

  return ;
}
0 голосов
/ 19 ноября 2011

Как сказал компетентный_техник, вы не хотите каждый раз воссоздавать тестовый массив.

Я не совсем уверен в этом, но почему бы не инициализировать byte[] test = null; в byte[] test = sData.Length; и удалить test = new byte[block.Length + pos]; из цикла?

...