سؤال

أريد أن أكتب biginterger إلى ملف.
ما هي أفضل طريقة للقيام بذلك.
بالطبع أريد أن أقرأ (مع البرنامج، وليس عن طريق الإنسان) ذلك من inputstream.
هل يجب علي استخدام ObsesoutPuttream أو هل هناك طرق أفضل؟

الغرض هو استخدام أقل بايت قدر الإمكان.

شكرًا
Martijn.

هل كانت مفيدة؟

المحلول

تسلسل جافا (ObjectOutputStream/ObjectInputStream) هو وسيلة للأغراض العامة، إيه، تسلسل الأشياء في تسلسل الثمانية. ومع ذلك، هناك قضية مع التسلسل.

أن تكون فعالة Uber، BigInteger لديها toByteArray والبناء الذي يأخذ byte[]. وبعد ثم تحتاج إلى بعض الطريق لتمثيل byte[] (بما في ذلك الطول) في مجرى. على سبيل المثال، يمكنك استخدام DataOutputStream ل writeInt الطول، واتبع ذلك مع البيانات الخام.

يمكن ضغط الجداول، بالطبع، مع ديكور مناسب من اختيارك.

نصائح أخرى

سأذهب مع ObjectOutPuttream، وهذا ما تم تصميمه ل (وليس bigintereger على وجه التحديد، ولكن الفصول).

فيما يلي بعض التعليمات البرمجية السريعة التي تعرض النفقات العامة لكلا المظهرين المضغوط وغير المضغوط.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPOutputStream;


public class Main
{
    public static void main(String[] args)
        throws IOException
    {
        run(1);
        run(10);
        run(100);
        run(1000);
        run(10000);
        run(100000);
        run(1000000);
    }

    private static void run(final int size)
        throws IOException
    {
        final List<BigInteger> values;
        final int              uncompressedSize;
        final int              compressedSize;

        values           = createValues(size);
        uncompressedSize = storeUncompressed(values);
        compressedSize   = storeCompressed(values);

        System.out.println(size + " uncompressed is " + uncompressedSize + " ratio is: " + ((float)uncompressedSize / size));
        System.out.println(size + " compressed   is " + compressedSize   + " ratio is: " + ((float)compressedSize   / size));
    }

    private static List<BigInteger> createValues(final int size)
    {
        final List<BigInteger> values;

        values = new ArrayList<BigInteger>(size);

        for(int i = 0; i < size; i++)
        {
            values.add(BigInteger.ZERO);
        }

        return (values);
    }

    private static int storeUncompressed(final List<BigInteger> values)
        throws IOException
    {
        final ByteArrayOutputStream bytes;

        bytes = new ByteArrayOutputStream();
        store(values, bytes);

        return (bytes.size());
    }


    private static int storeCompressed(final List<BigInteger> values)
        throws IOException
    {
        final ByteArrayOutputStream bytes;
        final GZIPOutputStream      zip;

        bytes = new ByteArrayOutputStream();
        zip   = new GZIPOutputStream(bytes);
        store(values, zip);

        return (bytes.size());
    }

    private static void store(final List<BigInteger> values,
                              final OutputStream     sink)
        throws IOException
    {
        ObjectOutputStream stream;

        stream = null;

        try
        {
            stream = new ObjectOutputStream(sink);

            for(final BigInteger value : values)
            {
                stream.writeObject(value);
            }
        }
        finally
        {
            if(stream != null)
            {
                stream.close();
            }
        }
    }
}

الإخراج هو:

1 uncompressed is 202 ratio is: 202.0
1 compressed   is 198 ratio is: 198.0
10 uncompressed is 247 ratio is: 24.7
10 compressed   is 205 ratio is: 20.5
100 uncompressed is 697 ratio is: 6.97
100 compressed   is 207 ratio is: 2.07
1000 uncompressed is 5197 ratio is: 5.197
1000 compressed   is 234 ratio is: 0.234
10000 uncompressed is 50197 ratio is: 5.0197
10000 compressed   is 308 ratio is: 0.0308
100000 uncompressed is 500197 ratio is: 5.00197
100000 compressed   is 962 ratio is: 0.00962
1000000 uncompressed is 5000197 ratio is: 5.000197
1000000 compressed   is 7516 ratio is: 0.007516

يمكنك تغيير "القيم" (biginteger.zero)؛ " خط لجعل الاختبار أكثر واقعية - أردت فقط خط الأساس لذلك.

تحرير: لم أكن أدرك أن السؤال هو التحسين.

يمكنك ضغط الكائن المسلسل بعد حفظ بعض البايتات. حاول استخدام ما يلي.

FileOutputStream fos = new 
    FileOutputStream("db");
  GZIPOutputStream gz = new GZIPOutputStream(fos);

هنا مقال عن طريق الشمس حول هذا الموضوع.

نعم، يمكنك استخدام ObjectoutPuttream / ObjectInPuttream للبساطة، أو يمكنك تحويل biginteger إلى البايت []، وتسلسل هذه القيمة بدلا من الكائن بأكمله. هذا الأخير سيوفر قدرا كبيرا من مساحة التخزين على تسلسل الكائن بأكمله.

أيضا، إذا كنت تستخدم فئات الدفق غير المؤقتة بالفعل، تذكر أن تلتف إخراجك والمكفول في Bufferedouttrestream وتحسين الأداء، ومسخ () بعد الانتهاء من الكتابة (إذا كنت لا تدفع () قد تتوقف Inputstream أو تعلق في انتظار الإدخال).

إذا كنت قلقا بشأن عرض النطاق الترددي أو حجم الملف، فيمكنك أيضا لف تياراتك في gzipoutputstream / gzipinputstream للضغط التلقائي. لا تقلق بشأن ضغط البيانات إلا إذا لاحظت فعلا أداء ضعيف أو ملفات ضخمة، ولكن

هل ترغب في قراءة / كتابة الكل Object أو فقط لها القيمةب إذا كان السابق، ثم الاستفادة من تسلسل. وبعد إذا كان الأخير، ثم الاستفادة من ByteArrayInputStream/ByteArrayOutputStream حيث تكتب نتيجة BigInteger#toByteArray() وبناء واحدة جديدة بمساعدة new BigInteger(byte[]) على التوالى. من الواضح أن الطريقة الأخيرة تولد بايت أقل بكثير في الملف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top