Можно ли сжать и загрузить эту строку в Amazon S3, не записывая ее на диск? - PullRequest
8 голосов
/ 05 апреля 2010

Я знаю, что это возможно при использовании Streams, но я не был уверен в правильном синтаксисе.

Я хотел бы передать строку в метод Save, чтобы она распаковала строку и загрузила ее в Amazon S3, не записывая ее на диск. Текущий метод неэффективно читает / записывает на диск между ними.

S3 PutObjectRequest имеет конструктор с вводом InputStream в качестве опции.

import java.io.*;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.PutObjectRequest;

public class FileStore {

    public static void Save(String data) throws IOException
    {
        File file = File.createTempFile("filemaster-", ".htm");
        file.deleteOnExit();

        Writer writer = new OutputStreamWriter(new FileOutputStream(file));
        writer.write(data);
        writer.flush();
        writer.close();

        String zippedFilename = gzipFile(file.getAbsolutePath());
        File zippedFile = new File(zippedFilename);
        zippedFile.deleteOnExit();

        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(
                new FileInputStream("AwsCredentials.properties")));

        String bucketName = "mybucket";
        String key = "test/" + zippedFile.getName();

        s3.putObject(new PutObjectRequest(bucketName, key, zippedFile));

    }

    public static String gzipFile(String filename) throws IOException
    {
        try {
            // Create the GZIP output stream
            String outFilename = filename + ".gz";
            GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(outFilename));

            // Open the input file
            FileInputStream in = new FileInputStream(filename);

            // Transfer bytes from the input file to the GZIP output stream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();

            // Complete the GZIP file
            out.finish();
            out.close();

            return outFilename;
        } catch (IOException e) {
            throw e;
        }
    }


}

Ответы [ 2 ]

7 голосов
/ 06 апреля 2010

Это по сути то, что предложили Аперкинс. Я не знаю интерфейса с AS3, поэтому его предложение создать ByteArrayInputStream поверх байтового массива, вероятно, является подходящим вариантом.

import java.io.*;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.PutObjectRequest;

public class FileStore {
    public static void Save(String data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        Writer writer = new OutputStreamWriter(baos);
        writer.write(data);
        writer.flush();
        writer.close();

        byte[] zippedBytes = gzipFile(baos.toByteArray());

        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(
            new FileInputStream("AwsCredentials.properties")));

        String bucketName = "mybucket";
        String key = "test/" + zippedFile.getName();

        s3.putObject(new PutObjectRequest(bucketName, key,
            new ByteArrayInputStream(zippedBytes));
    }

    public static byte[] gzipFile(byte[] bytes) throws IOException {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            GZIPOutputStream out = new GZIPOutputStream(baos);
            out.write(bytes, 0, bytes.length);
            // Complete the GZIP file
            out.finish();
            out.close();

            return baos.toByteArray();
        } catch (IOException e) {
            throw e;
        }
    }
}
7 голосов
/ 06 апреля 2010

Я бы использовал что-то вроде следующего:

ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
GZipOuputStream gzipOut = new GZipOutputStream(byteOut);
// write your stuff
byte[] bites = byteOut.toByteArray();
//write the bites to the amazon stream

Вы записываете сжатые значения в поток байтов, а затем берете значения байтов, и вы можете записать их в другой поток. Вы также можете перенести поток на сайт amazon (то есть поток вывода из http-соединения или чего-то подобного) и избежать всего ByteArrayOutputStream.


Редактировать: я заметил ваше последнее предложение - bleah. Вы можете взять созданные вами байты, создать с ними ByteArrayInputStream, а затем передать его в качестве входного потока:

ByteArrayInputStream byteInStream = new ByteArrayInputStream(bites);

Он должен читать из входного потока в выходной поток, если я правильно понимаю, что вы описываете правильно. В противном случае вы можете просто записать в выходной поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...