mohammaddx
چهارشنبه 29 مهر 1394, 22:40 عصر
با سلام به همه ی دوستان.من با جاوا اشنایی چندانی ندارم و بیشتر با c++ کار کردم.
من با file,filereader,bufferedreader یک فایل رو شروع به خواندن کردم و با readline ده خط به پایین رفته ام.حالا میخوام یه bufferedreader جدید بسازم که به این محل اشاره کنه و با این bufferedreader جدید تا خط 20 ادامه بدم ولی همچنان bufferedreader اولیه به همان خط 10 اشاره کنه.
مشکلم اینجاست که وقتی bufferedreader دومی را برابر bufferedreader اولی قرار میدم در هرواقع هر دو به یک جا اشاره میکنند که در صورت تغییر مکان دومی,مکان اولی نیز تغییر میکند یعنی هردو به خط 20 اشاره میکنند. ولی نمیخوام این طور باشه.
لطفا کمک کنید.با تشکر
Raminab
شنبه 02 آبان 1394, 19:13 عصر
سلام
اگه حتما میخوای از bufferedreader استفاده کنی میتونی هرجا خواستی mark رو صدا بزنی بعد که به این position احتیاج پیدا کردی reset کنی ولی این تا جایی که من میدونم فقط ی حالت قبل رو نگه میداره
اگه اصراری به استفاده از bufferedreader نداری RandomAccessFile فایل استفاده کن کد زیر رو امتحانی زدم کاری که میخواستی رو انجام میده
RandomAccessFile raf = new RandomAccessFile("Your Path","r");
System.out.println(raf.readLine());
System.out.println(raf.readLine());
System.out.println(raf.readLine());
System.out.println(raf.readLine());
long t = raf.getFilePointer();
System.out.println(raf.readLine());
System.out.println(raf.readLine());
raf.seek(t);
System.out.println(raf.readLine());
System.out.println(raf.readLine());
پرینت ها برای مطمین شدن از کده :لبخند: و با getFilePointer مکان فعلی پوینتر فایل رو ذخیره میکنیم و با seek میریم به جایی که ذخیره کرده بودیم . حالا اگه شما میخواین چند بار این کار رو انجام بدید میتونید یه ارایه از long یگیرید و الی اخر ...
ahmad.mo74
پنج شنبه 07 آبان 1394, 22:32 عصر
برای اینکار باید از متد skip استفاده کنید و تعداد کاراکترهایی که باید skip کنه رو هم بهش بدید. که این تعداد رو باید موقع خوندن خط ها حساب کنید که مشکلاتی هم ممکنه پیش بیاد چون تابع readLine میره خط بعدی رو میخونه اما ما نمیتونیم بفهمیم که خطوط با n\ یا r\ یا r\n\ جدا شده بودن از هم... بخاطر همین برای شمردن تعداد کاراکترها دچار مشکل میشیم. مثلا :
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* @author ahmad
*/
public class Test {
public static void main(String[] args) throws IOException {
long chars = 0;
int lines = 0;
String fileName = "some.txt";
try (BufferedReader r1 = newBufferedReader(fileName)) {
String line;
while ((line = r1.readLine()) != null) {
chars += line.length() + 2 /* \r\n */;
System.out.println("r1 -> " + line);
if (++lines == 5) {
try (BufferedReader r2 = newBufferedReader(fileName, chars)) {
while ((line = r2.readLine()) != null) {
System.out.println("r2 -> " + line);
}
}
}
}
}
}
public static BufferedReader newBufferedReader(String fileName) throws IOException {
return new BufferedReader(new FileReader(fileName));
}
public static BufferedReader newBufferedReader(String fileName, long skip) throws IOException {
final BufferedReader reader = new BufferedReader(new FileReader(fileName));
reader.skip(skip);
return reader;
}
}
اما مثلا میتونیم با تابع read کاراکترهارو بخونیم و به راحتی تعداد کاراکترهایی که خونده شده رو حساب کنیم اما اونوقت وظیفه جدا کردن خط ها به عهده خودمونه.
بهترین کار اینه که تعداد خط هایی که خونده شده رو نگه داریم و reader جدید به همون تعداد خطوط رو بخونه بره جلو تا به خطی که میخوایم برسه.
ویرایش :
راهی که آقای Raminab پیشنهاد دادن درست بود اما مشکلی که هست اینه که RandomAccessFile از buffer استفاده نمیکنه و خوندن خطوط باهاش به شدت کند میشه.
اما موقع استفاده از BufferedReader هم برای اینکه به موقعیت x برسیم مجبوریم تا اونجارو بخونیم و تابع skip هم صرفا بایت هارو میخونه و رد میشه! (یعنی بازم داریم محتویات فایل رو قبل از موقعیت x میخونیم و مستقیما از نقطه ای که میخواستیم شروع به خوندن نکردیم)
از کلاس های java.nio.channels.FileChannel و java.nio.MappedByteBuffer استفاده میکنیم.
هم میتونیم خیلی سریع و با استفاده از buffer فایلمونو بخونیم هم اینکه مستقیما از همون نقطه ای که دلمون میخواد شروع به خوندن کنیم :
RandomAccessLineReader :
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Objects;
/**
* @author ahmad
*/
public final class RandomAccessLineReader implements Cloneable, AutoCloseable {
private static final int DEFAULT_BUFFER_SIZE = 8192;
private static final char CR = '\r';
private static final char LF = '\n';
private final String src;
private final Charset charset;
private final int bufferSize;
private final FileChannel inChannel;
private final MappedByteBuffer mbb;
private final StringBuilder lineBuffer = new StringBuilder();
private int start;
private boolean ignoreLF;
private int absolutePosition = 0;
private int endOfLinePosition = 0;
public RandomAccessLineReader(String src) throws IOException {
this(src, StandardCharsets.UTF_8, DEFAULT_BUFFER_SIZE);
}
public RandomAccessLineReader(String src, Charset charset) throws IOException {
this(src, charset, DEFAULT_BUFFER_SIZE);
}
public RandomAccessLineReader(String src, int bufferSize) throws IOException {
this(src, StandardCharsets.UTF_8, bufferSize);
}
public RandomAccessLineReader(String src, Charset charset, int bufferSize) throws IOException {
Objects.requireNonNull(src);
Objects.requireNonNull(charset);
if (bufferSize <= 0) {
throw new IllegalArgumentException("bufferSize must be a positive integer");
}
this.src = src;
this.charset = charset;
this.bufferSize = bufferSize;
inChannel = FileChannel.open(Paths.get(src), StandardOpenOption.READ);
mbb = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
}
public synchronized String readLine() throws IOException {
if (absolutePosition == -1) {
throw new IOException("Stream closed");
}
String line = extractLine(start);
if (line != null) {
return line;
}
int count, i;
while ((count = Math.min(mbb.remaining(), bufferSize)) > 0) {
byte[] bytes = new byte[count];
mbb.get(bytes);
absolutePosition += count;
i = lineBuffer.length();
lineBuffer.append(new String(bytes, charset));
line = extractLine(i);
if (line != null) {
return line;
}
}
final int n = lineBuffer.length();
return extract(n, n);
}
private String extractLine(int searchAt) {
final int n = lineBuffer.length();
for (int i = searchAt; i < n; i++) {
switch (lineBuffer.charAt(i)) {
case CR:
if (i < n - 1) {
return lineBuffer.charAt(i + 1) == LF ? extract(i, i + 2) : extract(i, i + 1);
} else {
ignoreLF = true;
return extract(i, i + 1);
}
case LF:
if (ignoreLF) {
ignoreLF = false;
start = 1;
} else {
return extract(i, i + 1);
}
}
ignoreLF = false;
}
return null;
}
private String extract(int end, int next) {
final int n = lineBuffer.length();
if (n <= 0) {
return null;
}
end = Math.min(end, n);
next = Math.min(next, n);
final String line = start > end ? null : lineBuffer.substring(start, end);
lineBuffer.delete(start = 0, next);
if (line != null) {
endOfLinePosition += line.getBytes(charset).length + next - end;
}
return line;
}
public int getAbsolutePosition() {
return absolutePosition;
}
public int getEndOfLinePosition() {
return endOfLinePosition;
}
public synchronized void setPosition(int position) throws IOException {
if (absolutePosition == -1) {
throw new IOException("Stream closed");
}
mbb.position(position);
lineBuffer.setLength(0);
absolutePosition = position;
endOfLinePosition = position;
}
@Override
@SuppressWarnings("CloneDoesntCallSuperClone")
public RandomAccessLineReader clone() {
final int p = absolutePosition;
if (p != -1) {
try {
RandomAccessLineReader reader = new RandomAccessLineReader(src, charset);
reader.setPosition(endOfLinePosition);
return reader;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public synchronized void close() throws IOException {
mbb.clear();
inChannel.close();
lineBuffer.delete(0, lineBuffer.length());
absolutePosition = -1;
endOfLinePosition = -1;
}
public static void main(String[] args) throws Exception {
int lines = 0;
try (RandomAccessLineReader r1 = new RandomAccessLineReader("some.txt")) {
String line;
while ((line = r1.readLine()) != null) {
System.out.println("r1 -> " + line);
if (++lines == 10) {
try (RandomAccessLineReader r2 = r1.clone()) {
if (r2 != null) {
while ((line = r2.readLine()) != null) {
System.out.println("r2 -> " + line);
}
}
}
}
}
}
}
}
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.