我一直在阅读关于finalize()的很多新手Java问题,并发现有点令人困惑的是,没有人真正说明finalize()是一种不可靠的清理资源的方法.我看到有人评论说他们用它来清理Connections,这真的很可怕,因为接近Connection的关闭的唯一方法就是最终实现try(catch).
我没有受过CS的教育,但是我已经用Java专业编程近十年了,我从未见过有人在生产系统中实现finalize().这仍然不意味着它没有它的用途,或者我与之合作过的人一直在做正确的事.
所以我的问题是,实现finalize()的用例是什么,无法通过语言中的其他进程或语法更可靠地处理?
请提供具体的方案或您的经验,只是重复Java教科书,或最终确定的用途是不够的,这不是这个问题的意图.
我目前正在使用InpuStream从我的服务器获取JSON响应.
我需要做两件事:
在逐个使用这两种方法时,这完全没有问题.
使用GSON进行解析:
Gson gson = new Gson();
Reader reader = new InputStreamReader (myInputStream);
Result result = gson.FrmJson(reader, Result.class)
Run Code Online (Sandbox Code Playgroud)
并将复制到SDCard
FileOutputStream f (...) f.write (buffer)
Run Code Online (Sandbox Code Playgroud)
它们都经过了测试.
问题是一旦解析完成,我想写入SDCard并且它会中断.我知道我的InputStream已关闭,这就是问题所在.
这里有一些接近我的问题:如何缓存InputStream以供多次使用
有没有办法改进该解决方案并提供我们可以使用的东西?
我的问题是,如果已经读取了Ring请求,我怎么能惯用它?
这是背景.我正在为Ring应用程序编写错误处理程序.发生错误时,我想记录错误,包括我可能需要重现的所有相关信息并修复错误.一个重要的信息是请求的主体.但是,:body值的有状态(因为它是一种java.io.InputStream对象)会导致问题.
具体来说,会发生一些中间件(ring.middleware.json/wrap-json-body在我的情况下是中间件)slurp在body InputStream对象上执行a ,这会更改对象的内部状态,以便将来调用slurp返回空字符串.因此,从请求图中有效地丢失了[内容].
我能想到的唯一解决方案是InputStream在可以读取正文之前抢先复制正文对象,以防我以后可能需要它.我不喜欢这种方法,因为在以后可能出现错误的情况下,对每个请求做一些工作似乎很笨拙.有更好的方法吗?
我需要能够重复使用java.io.InputStream多次,并且我认为以下代码可以工作,但它只能在第一次使用.
public class Clazz
{
private java.io.InputStream dbInputStream, firstDBInputStream;
private ArrayTable db;
public Clazz(java.io.InputStream defDB)
{
this.firstDBInputStream = defDB;
this.dbInputStream = defDB;
if (db == null)
throw new java.io.FileNotFoundException("Could not find the database at " + db);
if (dbInputStream.markSupported())
dbInputStream.mark(Integer.MAX_VALUE);
loadDatabaseToArrayTable();
}
public final void loadDatabaseToArrayTable() throws java.io.IOException
{
this.dbInputStream = firstDBInputStream;
if (dbInputStream.markSupported())
dbInputStream.reset();
java.util.Scanner fileScanner = new java.util.Scanner(dbInputStream);
String CSV = "";
for (int i = 0; fileScanner.hasNextLine(); i++)
CSV += fileScanner.nextLine() + "\n";
db …Run Code Online (Sandbox Code Playgroud) 假设我有一个源自某个图像文件的互联网的inputStream.
我希望获得有关图像文件的信息,然后才能对其进行解码.
它可用于多种用途,例如下采样以及在显示图像之前预览信息.
我试图通过使用BufferedInputStream包装inputStream来标记和重置inputStream,但它不起作用:
inputStream=new BufferedInputStream(inputStream);
inputStream.mark(Integer.MAX_VALUE);
final BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeStream(inputStream,null,options);
//this works fine. i get the options filled just right.
inputStream.reset();
final Bitmap bitmap=BitmapFactory.decodeStream(inputStream,null,options);
//this returns null
Run Code Online (Sandbox Code Playgroud)
为了从网址中获取inputStream,我使用:
public static InputStream getInputStreamFromInternet(final String urlString)
{
try
{
final URL url=new URL(urlString);
final HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
final InputStream in=urlConnection.getInputStream();
return in;
}
catch(final Exception e)
{
e.printStackTrace();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如何让代码处理标记重置?
它与资源完美配合(实际上我甚至不需要创建一个新的BufferedInputStream来实现)但不能使用来自互联网的inputStream ...
编辑:
看来我的代码很好,有点......
在一些网站上(比如这一个和这个),即使重置后也无法解码图像文件.
如果您解码位图(并使用inSampleSize),它可以解码它(只需要很长时间).
现在的问题是它为什么会发生,我该如何解决它.
我有一个JAX-RS日志记录过滤器来记录请求和响应详细信息,如下所示:
public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
...
String body = getBody(request);
...
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("request: {}", httpRequest);
}
}
}
Run Code Online (Sandbox Code Playgroud)
该getBody()方法从中读取正文内容,InputStream但我需要做一些技巧,因为我无法重置此流.没有这个小技巧我的休息方法总是收到空的请求正文内容:
private String getBody(final ContainerRequestContext requestContext) {
try {
byte[] body = IOUtils.toByteArray(requestContext.getEntityStream());
InputStream stream = new ByteArrayInputStream(body);
requestContext.setEntityStream(stream);
return new String(body);
} catch (IOException e) {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来阅读身体内容?
Is there anyway to reuse an inputStream by changing its content? (Without new statement).
For instance, I was able to something very close to my requirement, but not enough
In the following code I am using a SequenceInputStream, and everytime I am adding a new InputStream to that sequence.
But I would like to do the same thing by using the same inputStream (I don't care which implementation of InputStream).
I thought about mark()/reset() APIs, but …