在二进制文件的中间插入字节

我想在图像元数据块的中间添加一些字符串。 根据某些特定标记。 我必须在字节级别上执行它,因为.NET不支持自定义元数据字段。

该块的构建类似于1C 02 XX YY YY ZZ ZZ ZZ ...其中XX是我需要追加的字段的ID,YY YY是它的大小,ZZ =数据。

我想应该或多或少地读取所有图像数据直到这个标记(1C 02 XX)然后增加大小字节(YY YY),在ZZ的末尾添加数据然后添加原始文件的其余部分? 它是否正确?

我该怎么做呢? 它需要使用4-5 MB JPEG文件尽可能快地工作。

通常,无法加速此操作。 您必须至少读取需要移动的部分并在更新的文件中再次写入。 如果可以并行化读写操作,则创建新文件并将内容复制到该文件可能会更快。

注意:在特定情况下,可能无法仅在文件中间插入内容,因为大多数文件格式的设计都没有考虑到这些修改。 通常,当您移动文件的一部分时,文件的某些部分会产生偏移。 指定您尝试使用的文件格式可以帮助其他人提供更好的方法。

解决了这段代码的问题:

  List dataNew = new List(); byte[] data = File.ReadAllBytes(jpegFilePath); int j = 0; for (int i = 1; i < data.Length; i++) { if (data[i - 1] == (byte)0x1C) // 1C IPTC { if (data[i] == (byte)0x02) // 02 IPTC { if (data[i + 1] == (byte)fileByte) // IPTC field_number, ie 0x78 = IPTC_120 { j = i; break; } } } } for (int i = 0; i < j + 2; i++) // add data from file before this field dataNew.Add(data[i]); int countOld = (data[j + 2] & 255) << 8 | (data[j + 3] & 255); // curr field length int countNew = valueToAdd.Length; // new string length int newfullSize = countOld + countNew; // sum byte[] newSize = BitConverter.GetBytes((Int16)newfullSize); // Int16 on 2 bytes (to use 2 bytes as size) Array.Reverse(newSize); // changes order 10 00 to 00 10 for (int i = 0; i < newSize.Length; i++) // add changed size dataNew.Add(newSize[i]); for (int i = j + 4; i < j + 4 + countOld; i++) // add old field value dataNew.Add(data[i]); byte[] newString = ASCIIEncoding.ASCII.GetBytes(valueToAdd); for (int i = 0; i < newString.Length; i++) // append with new field value dataNew.Add(newString[i]); for (int i = j + 4 + newfullSize; i < data.Length; i++) // add rest of the file dataNew.Add(data[i]); byte[] finalArray = dataNew.ToArray(); File.WriteAllBytes(Path.Combine(Path.GetDirectoryName(jpegFilePath), "newfile.jpg"), finalArray); 

这是一个简单而快速的解决方案。 它根据给定的extraBytes将给定偏移量后的所有字节移动到新位置,因此您可以插入数据。

 public void ExpandFile(FileStream stream, long offset, int extraBytes) { // http://stackoverflow.com/questions/3033771/file-io-with-streams-best-memory-buffer-size const int SIZE = 4096; var buffer = new byte[SIZE]; var length = stream.Length; // Expand file stream.SetLength(length + extraBytes); var pos = length; int to_read; while (pos > offset) { to_read = pos - SIZE >= offset ? SIZE : (int)(pos - offset); pos -= to_read; stream.Position = pos; stream.Read(buffer, 0, to_read); stream.Position = pos + extraBytes; stream.Write(buffer, 0, to_read); } 

需要检查,但……