File Seek in a dynamically increasing file
I am trying to save a online stream locally and then distribute the stream from my local node.
Program flow:
First request for a url, url-test, creates a single writer thread which starts writing to the fil开发者_Go百科e system with file name, url-file. All subsequent requests for that url, url-test, are handled from the local file system.
Writer Thread
protected class Writer implements Runnable {
String url;
public void run() {
FileOutputStream out_file = null;
File cacheFile = new File("url-file");
byte[] buf = new byte[4096];
int count = 0;
try {
URL urlstream = new URL(url);
// cv is an object which stores url information
cv.originInputStream = urlstream.openStream();
out_file = new FileOutputStream(cacheFile);
while ((count = cv.originInputStream.read(buf)) > 0) {
out_file.write(buf, 0, count);
out_file.flush();
cv.incrementTotalBytes(count);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now for the next request I need to read the locally saved file, url-file, and move to the last saved position in it. I am using totalBytes attribute of cv object which gives me total byte saved by the writer thread.
FileInputStream in = new FileInputStream("url-file");
response.setHeader("Content-Disposition", "inline; filename="
+ localFile.getName());
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "-1");
OutputStream out = response.getOutputStream();
// Copy the contents of the file to the output stream
byte[] buf = new byte[4096];
int count = 0;
FileChannel inc = in.getChannel();
ByteBuffer b = ByteBuffer.allocate(4096);
inc.position(cv.getTotalBytes());
while ((count = inc.read(b)) >= 0) {
out.write(b.array(), 0, count);
b.clear();
}
I do not see any output, what is the best way to seek in a file, which is getting updated by another thread.
EDIT: I expect the writer thread to keep on writing to the file and the response for any request should start from that instance of time. In nutshell, my writer thread is still writing to file when setting the position in the file channel. Even if I set the file channel position to 25% less say inc.position(totalBytes - (long) 0.25 * totalBytes)
I still do not see output.
It looks to me, that cv
holds a the number of total bytes in the file. There's an update call to cv
each time you append data to the file.
The second snippet seems to use the same value ("filesize") as a marker in the file channel. To my understanding, you always set the marker on the last byte in the file and try to start reading from that position and, obviously, you'll see EOF immediatly.
Rethink your method of calculating the starting position for the response. It shouldn't be the last byte at the file.
精彩评论