你怎么做呢?给定一个字节数组:
byte[] foo = new byte[4096];
Run Code Online (Sandbox Code Playgroud)
如何将数组的前x个字节作为单独的数组?(具体来说,我需要它作为一个IEnumerable<byte>)
这是为了与Sockets合作.我认为最简单的方法是数组切片,类似于Perls语法:
@bar = @foo[0..40];
Run Code Online (Sandbox Code Playgroud)
这会将前41个元素返回到@bar数组中.C#中有些东西我只是缺少,还是还有其他一些我应该做的事情?
LINQ对我来说是一个选项(.NET 3.5),如果这有帮助的话.
我正在将C应用程序移植到C#中.C应用程序从第三方DLL调用许多函数,所以我在C#中为这些函数编写了P/Invoke包装器.其中的一些C函数分配,我有在C#应用程序使用的数据,所以就用IntPtr的,Marshal.PtrToStructure并且Marshal.Copy到本机数据(数组和结构)复制到管理变量.
不幸的是,C#app被证明比C版慢得多.快速的性能分析表明,上述基于编组的数据复制是瓶颈.我正在考虑通过重写它以使用指针来加速C#代码.由于我没有C#中不安全的代码和指针的经验,我需要有关以下问题的专家意见:
unsafe代码和指针而不是IntPtr和Marshaling有什么缺点?例如,它是否以任何方式更不安全(双关语)?人们似乎更喜欢编组,但我不知道为什么.为了使情况更加清晰,我将一个小的示例代码(实际代码复杂得多)整合在一起.我希望这个例子说明我在谈论"不安全的代码和指针"与"IntPtr和Marshal"时的意思.
MyLib.h
#ifndef _MY_LIB_H_
#define _MY_LIB_H_
struct MyData
{
int length;
unsigned char* bytes;
};
__declspec(dllexport) void CreateMyData(struct MyData** myData, int length);
__declspec(dllexport) void DestroyMyData(struct MyData* myData);
#endif // _MY_LIB_H_
Run Code Online (Sandbox Code Playgroud)
MyLib.c
#include <stdlib.h>
#include "MyLib.h"
void CreateMyData(struct MyData** myData, int length)
{
int i;
*myData = (struct MyData*)malloc(sizeof(struct MyData));
if (*myData != NULL)
{
(*myData)->length = length; …Run Code Online (Sandbox Code Playgroud) 我已经介绍过了,现在我正在寻找可以从我的热点中挤出一切可能的性能.
我知道[MethodImplOptions.AggressiveInlining]和ProfileOptimization类.还有其他人吗?
[编辑] 我刚刚发现了[TargetedPatchingOptOut].没关系,显然不需要一个.
给定byte[] valuesC#中的填充,我想将值添加(byte)0x00到数组之前.我假设这将需要创建一个新数组并添加旧数组的内容.速度是我的应用程序的一个重要方面.做这个的最好方式是什么?
- 编辑 -
所述byte[]用于存储DSA(数字签名算法)的参数.每个阵列只需执行一次操作,但速度很重要,因为我可能在许多不同的byte[]s 上执行此操作.
我的应用程序从TCP套接字读取字节并需要缓冲它们,以便我可以稍后从中提取消息.由于TCP的性质,我可能在一次读取中得到部分或多个消息,因此在每次读取之后,我想检查缓冲区并提取尽可能多的完整消息.
因此,我想要一个允许我执行以下操作的课程:
我希望我想要的可以用.NET库中的一个或多个现有类来完成,但我不确定哪些类.System.IO.MemoryStream看起来接近我想要的,但是(a)不清楚它是否适合用作缓冲区(读取数据是否从容量中删除?)和(b)读写似乎发生在同一个地方 - "流的当前位置是下一次读取或写入操作可能发生的位置." - 这不是我想要的.我需要写到最后并从前面阅读.
我需要帮助将非常大的二进制文件(ZIP文件)转换为Base64String并再次返回.这些文件太大而无法一次性加载到内存中(它们会抛出OutOfMemoryExceptions),否则这将是一项简单的任务.我不想单独处理ZIP文件的内容,我想处理整个ZIP文件.
问题:
我可以将整个ZIP文件(测试大小从1 MB到目前的800 MB)转换为Base64String,但是当我将其转换回来时,它已被破坏.新的ZIP文件大小正确,它被Windows和WinRAR/7-Zip等识别为ZIP文件,我甚至可以查看ZIP文件内部并查看具有正确尺寸/属性的内容,但是当我试图从ZIP文件中提取,我得到:"错误:0x80004005"这是一般错误代码.
我不确定腐败发生的地点或原因.我做了一些调查,我注意到以下几点:
如果您有一个大文本文件,您可以逐步将其转换为Base64String而不会出现问题.如果调用Convert.ToBase64String整个文件产生:"abcdefghijklmnopqrstuvwx",那么在文件中分两部分调用它将产生:"abcdefghijkl"和"mnopqrstuvwx".
不幸的是,如果文件是二进制文件,那么结果就不同了.虽然整个文件可能会产生:"abcdefghijklmnopqrstuvwx",尝试将其分为两部分会产生类似:"oiweh87yakgb"和"kyckshfguywp".
有没有办法逐步基础64编码二进制文件,同时避免这种损坏?
我的代码:
private void ConvertLargeFile()
{
FileStream inputStream = new FileStream("C:\\Users\\test\\Desktop\\my.zip", FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[MultipleOfThree];
int bytesRead = inputStream.Read(buffer, 0, buffer.Length);
while(bytesRead > 0)
{
byte[] secondaryBuffer = new byte[buffer.Length];
int secondaryBufferBytesRead = bytesRead;
Array.Copy(buffer, secondaryBuffer, buffer.Length);
bool isFinalChunk = false;
Array.Clear(buffer, 0, buffer.Length);
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
if(bytesRead == …Run Code Online (Sandbox Code Playgroud) 我有一个包含int []数组的C#类(以及其他几个字段,但数组是主要的).代码经常创建此类的副本,并且分析显示复制此数组的Array.Copy()调用需要花费大量时间.我该怎么做才能让它更快?
数组大小非常小且恒定:12个元素.理想情况下,我喜欢类似C风格的数组:类本身内部的单个内存块(不是指针).这可能在C#中吗?(如果需要,我可以使用不安全的代码.)
我已经尝试过了:
1)使用UIn64和位移代替数组.(每个元素的值也非常小.)这确实使复制速度快,但整体上减慢了程序的速度.
2)为每个数组元素使用单独的字段:int element0,int element1,int element2等.同样,当我必须访问给定索引处的元素时,这总体上较慢.
我有一个NetworkStream用于从另一个程序获取数据.数据以Byte [64]的形式到达,然后我将其排入ConcurrentQueue,以便其他线程可以在以后出列以进行分析.队列被实例化:
ConcurrentQueue<byte[]> fifo = new ConcurrentQueue<byte[]>();
Run Code Online (Sandbox Code Playgroud)
然后我排队发送的所有数据:
Byte[] bytesIn = new Byte[64];
int i;
while ((i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0)
{
fifo.Enqueue(bytesIn);
}
Run Code Online (Sandbox Code Playgroud)
如果我然后查看(在调试期间),其中的数据fifo结果表明包含的每个字节[64]与最新的相同bytesIn.我如何确保我添加的数组fifo是值而不是指针(如果这是正确的术语)?
C#的List <>有一组CopyTo函数,它们使用快速内存块拷贝将其内部数组的内容提取到另一个数组中.
有没有办法反过来做到这一点?它可能看起来像......
var buffer = new List<byte>();
buffer.AddRange(afewbytes);
buffer.AddFromArray(myArray, startIndex, countBytesToCopy);
buffer.AddRange(afewmorebytes);
Run Code Online (Sandbox Code Playgroud)
由于我的List是List <byte>变种,我宁愿避免一个逐字节复制的循环.
我需要从字节数组中获取特定字节。我知道我想要的第一个字节的内容,之后我需要 x 个字节。
例如,我有
byte [] readbuffer { 0, 1, 2, 0x55, 3, 4, 5, 6};
byte [] results = new byte[30];
Run Code Online (Sandbox Code Playgroud)
我需要出现在“0x55”之后的 3 个字节
byte results == {ox55aa, 3, 4, 5}
Run Code Online (Sandbox Code Playgroud)
我正在使用:
Array.copy(readbuffer, "need the index of 0x55" ,results, 0, 3);
Run Code Online (Sandbox Code Playgroud)
我需要找到 0x55 的索引
PS:0x55在数组中处于任意位置。PS2:我之前忘了提到我在 .Net Micro Framework 中工作。
(我很抱歉非代码描述,我是编程的新手......和英语)
先感谢您
[编辑]x2
我有两个字节数组.我想将这两个字节数组合并为一个字节数组.
通常,我只是创建一个新的字节数组,其长度为= byte array#1 + byte array#2.然后将字节数组#1和#2复制到新的字节数组.
有没有一种更有效的方法来使用VB.NET和.NET 4合并两个字节数组?