7

我正在尝试从 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();
            }
        }

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

更新:

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

4

6 回答 6

6

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

ClientConfiguration config = new ClientConfiguration();
config.setSocketTimeout(0);
AmazonS3 s3 = new AmazonS3Client(/* credentials */, config);
于 2012-12-19T12:36:37.370 回答
2

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

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

我已经让它保持对 AmazonS3 对象的引用,这解决了我的问题。

于 2013-10-22T20:14:50.667 回答
1

也许您应该在 finally 而不是“in”中关闭 readerS3。即关闭最外面的对象,它可以关闭它的包裹子对象。

如果您先关闭“in”,则 InputStreamReader 和 BufferedReader 仍处于打开状态,并且如果他们尝试对所包装的对象执行任何操作,则该对象将已关闭。

于 2012-10-06T08:54:04.613 回答
0

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

于 2012-07-11T22:38:21.373 回答
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"));
 }
于 2016-06-06T18:18:33.053 回答
0

我遇到了同样的问题,这个主题帮助我解决了这个问题:S3 Java 客户端因“内容长度分隔的消息体过早结束”或“java.net.SocketException 套接字已关闭”而失败了很多

基本上我为每个文件创建了一个新的 S3Client 对象,但有一次这个对象被垃圾收集了。因此,我没有这样做,而是将我的班级改为使用 Singleton :

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

  public AmazonS3 getService() {
    return s3Client;
  }
于 2016-12-05T18:23:17.587 回答