读取S3文件时“java.net.SocketException:Socket已关闭”

时间:2012-07-11 20:24:54

标签: java file-io amazon-s3

我正在尝试从S3读取csv文本文件,然后将其每一行发送到分布式队列以进行处理。

当试图读取它时,我得到“java.net.SocketException:Socket is closed”正在读取的文件的不同点的异常(在不同的执行中)。这是代码:

      AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(MyClass.class.getResourceAsStream("myCredentials.properties")));

        String bucketName = "myBucket";
        String key = "myFile";  

        S3Object object = s3.getObject(new GetObjectRequest(bucketName, key));

        InputStream in = object.getObjectContent();

        BufferedReader readerS3 = new BufferedReader(new InputStreamReader(in, Charset.forName(fileInfo.getEncoding())));

        try {
            String line = null;
            while ((line = readerS3.readLine()) != null) {
                // Sending the line to a distributed queue
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

关于如何解决这个问题的任何想法?

更新:

从第二次运行方法时发生此异常,如果我停止整个程序并再次运行它,那么第一次运行该方法就可以了。

6 个答案:

答案 0 :(得分:6)

正如“jsn”在评论的评论中所建议的那样,问题是您需要使用ClientConfiguration配置AmazonS3

ClientConfiguration config = new ClientConfiguration();
config.setSocketTimeout(0);
AmazonS3 s3 = new AmazonS3Client(/* credentials */, config);

答案 1 :(得分:2)

谢谢,@ jsn,你的建议是我的问题。

我有一个方法只返回InputStream,因此AmazonS3对象被垃圾收集并导致它关闭InputStream。

我已经让它保留了对AmazonS3对象的引用并解决了我的问题。

答案 2 :(得分:1)

也许你应该在你的终结中关闭readerS3而不是'in'。即关闭最外面的对象,它可以关闭它的包装儿童。

如果你先关闭'in',那么InputStreamReader和BufferedReader仍然是打开的,如果他们试图对它们包装的对象做任何事情,它就会被关闭。

答案 3 :(得分:0)

关闭套接字的输入流或输出流,或者围绕它们的任何流/读取器/编写器包装器,关闭套接字(分别关闭输出或输入流)。

答案 4 :(得分:0)

无需继续重新初始化s3。

onCreate上的

调用初始化s3Object和s3Client。

然后在你的asynctask中使用调用

通过这种方式,你的s3Client将保留相同的数据,并且在执行while读取时永远不会关闭与s3的套接字连接。要聪明并学习。

S3Client s3Client;
S3Object s3Object;

onCreate() {
 s3Client = new AmazonS3Client(new BasicSessionCredentials(Constants.ACCESS_KEY_ID, Constants.SECRET_KEY, Constants.TOKEN));

 object = new S3Object();
}

doinbackground() {
      object = s3Client.getObject(new GetObjectRequest(Constants.getBucket(), id +".png"));
 }

答案 5 :(得分:0)

我遇到了同样的问题,这个问题帮助我解决了这个问题:S3 Java client fails a lot with "Premature end of Content-Length delimited message body" or "java.net.SocketException Socket closed"

基本上我是为每个文件创建一个新的S3Client对象,但是在某个时刻这个对象被垃圾收集了。因此,我没有这样做,而是将我的类转换为使用Singleton:

private static AmazonS3 s3Client;
  static {
    s3Client = new AmazonS3Client(new BasicAWSCredentials(AWSKey, AWSSecretKey));
  }

  public AmazonS3 getService() {
    return s3Client;
  }