使 InputStream 读取多次,无论 markSupported() 是什么
我需要能够多次重复使用 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 = ArrayTable.createArrayTableFromCSV(CSV);
}
public void reloadDatabase()//A method called by the UI
{
try
{
loadDatabaseToArrayTable();
}
catch (Throwable t)
{
//Alert the user that an error has occurred
}
}
}
请注意,ArrayTable 是我的一个类,它使用数组提供处理表的接口。
问题
在这个程序中,在调用 reloadDatabase()
方法后,数据库立即直接向用户显示,因此任何涉及将初始读取保存到内存中的对象的解决方案都是无用的,因为这将不要刷新数据(将其想象为浏览器;当您按“刷新”时,您希望它再次获取信息,而不仅仅是显示第一次获取的信息)。 如何多次读取java.io.InputStream
?
I need to be able to re-use a java.io.InputStream
multiple times, and I figured the following code would work, but it only works the first time.
Code
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 = ArrayTable.createArrayTableFromCSV(CSV);
}
public void reloadDatabase()//A method called by the UI
{
try
{
loadDatabaseToArrayTable();
}
catch (Throwable t)
{
//Alert the user that an error has occurred
}
}
}
Note that ArrayTable is a class of mine, which uses arrays to give an interface for working with tables.
Question
In this program, the database is shown directly to the user immediately after the reloadDatabase()
method is called, and so any solution involving saving the initial read to an object in memory is useless, as that will NOT refresh the data (think of it like a browser; when you press "Refresh", you want it to fetch the information again, not just display the information it fetched the first time). How can I read a java.io.InputStream
more than once?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不一定可以多次读取 InputStream。有些实现支持它,有些不支持。您正在做的是检查 markSupported 方法,如果您可以读取同一个流两次,这确实是一个指示器,但您会忽略结果。您必须调用该方法来查看是否可以读取流两次,如果不能,请进行其他安排。
编辑(回应评论):当我写下答案时,我的“其他安排”是获得一个新的输入流。然而,当我读到你对你想做什么的问题的评论时,我不确定这是可能的。对于操作的基础知识,您可能需要 RandomAccessFile (至少这是我的第一个猜测,如果它有效,那将是最简单的) - 但是您将遇到文件访问问题。您有一个应用程序主动写入文件,而另一个应用程序正在读取该文件,您将遇到问题 - 具体哪些问题将取决于操作系统,因此无论什么解决方案都需要更多测试。我建议就这一点提出一个单独的问题,尝试过这个问题的人也许可以给你更多的见解。
You can't necessarily read an InputStream more than once. Some implementations support it, some don't. What you are doing is checking the markSupported method, which is indeed an indicator if you can read the same stream twice, but then you are ignoring the result. You have to call that method to see if you can read the stream twice, and if you can't, make other arrangements.
Edit (in response to comment): When I wrote my answer, my "other arrangements" was to get a fresh InputStream. However, when I read in your comments to your question about what you want to do, I'm not sure it is possible. For the basics of the operation, you probably want RandomAccessFile (at least that would be my first guess, and if it worked, that would be the easiest) - however you will have file access issues. You have an application actively writing to a file, and another reading that file, you will have problems - exactly which problems will depend on the OS, so whatever solution would require more testing. I suggest a separate question on SO that hits on that point, and someone who has tried that out can perhaps give you more insight.
您永远不会将流标记为要重置,
但是您可以保留原始 ArrayTable 的副本,并在需要时复制该副本(甚至是创建的字符串来重建它),
此代码会创建字符串并缓存它,以便您可以安全地丢弃输入流,只需使用
readCSV
构建ArrayTable
,但是如果您需要新信息,则需要创建一个新流才能再次读取
you never mark the stream to be reset
however you could instead keep a copy of the original ArrayTable and copy that when you need to (or even the created string to rebuild it)
this code creates the string and caches it so you can safely discard the inputstreams and just use
readCSV
to build theArrayTable
however if you want new information you'll need to create a new stream to read from again