我正在尝试从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();
}
}
关于如何解决这个问题的任何想法?
更新:
从第二次运行方法时发生此异常,如果我停止整个程序并再次运行它,那么第一次运行该方法就可以了。
答案 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;
}