문제

내가 있는 클래스가 필요하는 바이너리를 직렬화.클래스가 포함 하나의 필드 아래와 같:

private T[,] m_data;

이러한 다중 차원 배열할 수 있습니다 상당히 큰(수백 수천의 요소)와의 기본 유형입니다.가 표준입니다.net 직렬화 개체에 대한 파일에 기록하는 디스크가 큰 나는 생각한다.그물이 저장 많이 반복된 데이터에 대해 요소의 종류와 가능하지 효율적으로 사용할 수 있습니다.

을 봤어요 주위 사용자 지정 직렬화하지만 보지 않은 어떤 다루는 다중 차원 일반적인 배열입니다.나는 또한 실험과 함께 내장되어 있습니다.net 압축에서의 바이트 배열은 메모리를 스트림을 다음과 같은 직렬화와 몇 가지 성공을,하지만 빠른/압축으로 기대했는데요.

나의 질문은,해야 하려고 쓰기 사용자 지정 serializer 을 최적으로 직렬화 이 배열에 대한 적절한 형식(이것은 어떤),또는 사용해야 하는 표준입니다.net 직렬화를 추가 압축?

에 대한 조언이 최선의 방법이 될 것이 가장 감사,또는 자료에 대한 링크를 보여주는 해결하는 방법에 대해 직렬화의 다중 차원 일반적인 배열 상황 기존 예 내가 찾은 지원하지 않는 같은 구조입니다.

도움이 되었습니까?

해결책

여기 내가 생각해 낸 것입니다. 아래 코드는 int [1000] [10000]을 만들고 Binaryformatter를 2 개의 파일에 사용하여 하나의 ZIPPENT 및 NOT을 사용하지 않습니다.

지퍼 파일은 1.19MB (1,255,339 바이트) 압축이 없음 38.2MB (40,150,034 바이트)입니다.

        int width = 1000;
        int height = 10000;
        List<int[]> list = new List<int[]>();
        for (int i = 0; i < height; i++)
        {
            list.Add(Enumerable.Range(0, width).ToArray());
        }
        int[][] bazillionInts = list.ToArray();
        using (FileStream fsZ = new FileStream("c:\\temp_zipped.txt", FileMode.Create))
        using (FileStream fs = new FileStream("c:\\temp_notZipped.txt", FileMode.Create))
        using (GZipStream gz = new GZipStream(fsZ, CompressionMode.Compress))
        {
            BinaryFormatter f = new BinaryFormatter();
            f.Serialize(gz, bazillionInts);
            f.Serialize(fs, bazillionInts);
        }

더 나은/쉬운 방법을 생각할 수 없습니다. 지퍼 버전은 꽤 빡빡합니다.

Binaryformatter + Gzipstream과 함께 갈 것입니다. 관습을 만드는 것은 전혀 재미 있지 않을 것입니다.


MG에 의해 편집] 편집에 의해 기분이 상하지 않기를 바랍니다. 그러나 균일 한 반복 범위 (0, 너비)는 사물을 크게 왜곡합니다. 로 변경:

        int width = 1000;
        int height = 10000;
        Random rand = new Random(123456);
        int[,] bazillionInts = new int[width, height];
        for(int i = 0 ; i < width;i++)
            for (int j = 0; j < height; j++)
            {
                bazillionInts[i, j] = rand.Next(50000);
            }

그리고 그것을 시도하십시오. 당신은 볼 수 temp_notZipped.txt 40MB에서 temp_zipped.txt 62MB에서. 그렇게 매력적이지 않습니다 ...

다른 팁

최고의 코드 길이/출력 크기의 비율은 인코딩하여 배열을 사용하여 BitConverter,변환 모든 요소로 그들의 컴팩트 바이너리 형식입니다.그것은 설명서,내가 알지만 저장됩니다 80-90%의 공간과 비교.순진 serialization.

"큰"을 정의 할 수 있습니까? 1000x10000xint 예제 (다른 게시물)는 40MB로 나옵니다. 및 1000x10000x4 바이트 (= int)는 38MB입니다. 오버 헤드가 갈수록 끔찍하지 않습니다.

어떤 종류의 데이터 일 가능성이 있습니까? 그냥 원시? 아마 편집 할 수 있다고 생각합니다 protobuf-net 직사각형 배열을 지원합니다* - 그러나 어떤 종류의 와이어 호환성을 유지하려면 헤더가 필요할 것입니다 (하나의 바이트). 요소 당 - 1000x10000 예제에 대한 즉, 9MB 오버 헤드.

이것은 아마도 같은 것들에 가치가 없을 것입니다 float, double, 등 ( "프로토콜 버퍼"아래에 구두로 저장되어 있기 때문에) - 그러나 int 단순히 int를 포장하는 방식으로 인해 ... (특히 더 작은면에있는 경향이 있다면 [크기]). 마지막으로 T가 실제로 객체 인 경우 Person 등, 그런 다음 a 많은 포장 물체에 매우 능숙하기 때문에 이진 직렬화보다 낫습니다.

직사각형 어레이에서 신발 뿔에는 사소하지는 않지만 이것이 당신이 시도하는 데 관심이 있는지 알려주십시오.

*: "프로토콜 버퍼"사양이 지원하지 않기 때문에 지금은 그렇지 않지만 우리는 그 주위를 해킹 할 수 있습니다 ...

유형에 대한 많은 데이터가 필요한 이유는 t의 배열이 어떤 유형이든, 구체적으로는 t 유형 일 수 있으며, 그 배열에 여전히 언급 된 클래스를 저장할 수 있기 때문에, deserializer가 필요할 것입니다. 이것을 알고 있습니다.

그러나이 중복 데이터는 다른 사람들이 언급했듯이 압축에 대한 좋은 후보입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top