See InputSteram.read(byte[]) for reading bytes at a time.
Example code:
try {
File file = new File("myFile");
FileInputStream is = new FileInputStream(file);
byte[] chunk = new byte[1024];
int chunkLen = 0;
while ((chunkLen = is.read(chunk)) != -1) {
// your code..
}
} catch (FileNotFoundException fnfE) {
// file not found, handle case
} catch (IOException ioE) {
// problem reading, handle case
}
Answer from cklab on Stack OverflowSee InputSteram.read(byte[]) for reading bytes at a time.
Example code:
try {
File file = new File("myFile");
FileInputStream is = new FileInputStream(file);
byte[] chunk = new byte[1024];
int chunkLen = 0;
while ((chunkLen = is.read(chunk)) != -1) {
// your code..
}
} catch (FileNotFoundException fnfE) {
// file not found, handle case
} catch (IOException ioE) {
// problem reading, handle case
}
what you want is source data line. This is perfect for when your data is too large to hold it in memory at once, so you can start playing it before you receive the entire file. Or if the file never ends.
look at the tutorial for source data line here
http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html#read
I would use this FileInputSteam
You can use the appropriate read() method from the input stream, for example FileInputStream supports a read(byte[]) to read a chunk of bytes.
something like: You may want to wrap the input stream in a BufferedInputStream if you wanted to guarantee 512 byte blocks (the constructor takes a block size argument).
byte[] buffer = new byte[512];
FileInputStream in = new FileInputStream("some_file");
int rc = in.read(buffer);
while(rc != -1)
{
// rc should contain the number of bytes read in this operation.
// do stuff...
// next read
rc = in.read(buffer);
}
You ... read 512 bytes at a time.
char[] myBuffer = new char[512];
int bytesRead = 0;
BufferedReader in = new BufferedReader(new FileReader("foo.txt"));
while ((bytesRead = in.read(myBuffer,0,512)) != -1)
{
...
}
To chunk your input use a FileInputStream:
Path pp = FileSystems.getDefault().getPath("logs", "access.log");
final int BUFFER_SIZE = 1024*1024; //this is actually bytes
FileInputStream fis = new FileInputStream(pp.toFile());
byte[] buffer = new byte[BUFFER_SIZE];
int read = 0;
while( ( read = fis.read( buffer ) ) > 0 ){
// call your other methodes here...
}
fis.close();
To stream a file, you need to step away from Files.readAllBytes(). It's a nice utility for small files, but as you noticed not so much for large files.
In pseudocode it would look something like this:
while there are more bytes available
read some bytes
process those bytes
(write the result back to a file, if needed)
In Java, you can use a FileInputStream to read a file byte by byte or chunk by chunk. Lets say we want to write back our processed bytes. First we open the files:
FileInputStream is = new FileInputStream(new File("input.txt"));
FileOutputStream os = new FileOutputStream(new File("output.txt"));
We need the FileOutputStream to write back our results - we don't want to just drop our precious processed data, right? Next we need a buffer which holds a chunk of bytes:
byte[] buf = new byte[4096];
How many bytes is up to you, I kinda like chunks of 4096 bytes. Then we need to actually read some bytes
int read = is.read(buf);
this will read up to buf.length bytes and store them in buf. It will return the total bytes read. Then we process the bytes:
//Assuming the processing function looks like this:
//byte[] process(byte[] data, int bytes);
byte[] ret = process(buf, read);
process() in above example is your processing method. It takes in a byte-array, the number of bytes it should process and returns the result as byte-array.
Last, we write the result back to a file:
os.write(ret);
We have to execute this in a loop until there are no bytes left in the file, so lets write a loop for it:
int read = 0;
while((read = is.read(buf)) > 0) {
byte[] ret = process(buf, read);
os.write(ret);
}
and finally close the streams
is.close();
os.close();
And thats it. We processed the file in 4096-byte chunks and wrote the result back to a file. It's up to you what to do with the result, you could also send it over TCP or even drop it if it's not needed, or even read from TCP instead of a file, the basic logic is the same.
This still needs some proper error-handling to work around missing files or wrong permissions but that's up to you to implement that.
A example implementation for the process method:
//returns the hex-representation of the bytes
public static byte[] process(byte[] bytes, int length) {
final char[] hexchars = "0123456789ABCDEF".toCharArray();
char[] ret = new char[length * 2];
for ( int i = 0; i < length; ++i) {
int b = bytes[i] & 0xFF;
ret[i * 2] = hexchars[b >>> 4];
ret[i * 2 + 1] = hexchars[b & 0x0F];
}
return ret;
}
The best thing you can do is to read your file line by line until you reach your patterns by doing something like that:
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new File(file), charset))
) {
String line;
boolean start = false;
// Read the file line by line
while ((line = br.readLine()) != null) {
if (start) {
// Here the start pattern has been found already
if (line.equals("{/AAAA}")) {
// The end pattern has been reached so we stop reading the file
break;
}
// The line is not the end pattern so we treat it
doSomething(line);
} else {
// Here we did not find the start pattern yet
// so we check if the line is the start pattern
start = line.equals("{AAAA}");
}
}
}
This way you only read your file until you reach the end pattern which will be more efficient than reading the entire file.
With Java 9 (still in beta), you could write something like:
try (Stream<String> lines = Files.lines(path, UTF_8)) {
result = lines.dropWhile(line -> !line.equals("{AAAA}")
.takeWhile(line -> !line.equals("{/AAAA}")
.collect(toList());
}
With Java 8 or earlier, a standard while loop seems more appropriate.