어떻게 사용하 Java 에서 읽을 수 있는 파일을 적극적으로 기록되니까?
문제
내가 있는 응용 프로그램 정보를 기록하는 파일입니다.이 정보를 사용 post-실행을 결정하는 통과/실패/어플리케이션의 정확성.고 싶할 파일을 읽을 수 있는 그대로 쓰고 있는 그래서 나는 이러한 작업을 수행 할 수 있습니다 통과/실패/정확성을 검사합니다.
나는 가정이 가능하지만,무엇을 잡았다의 관여 사용하는 경우 Java?는 경우 읽기 잡는다면,그것은 그냥 기다 더 많은 쓰는 최대 파일을 닫을 때까지,또는 읽을 던지 예외가 이 시점에서?후자의 경우,그때 나는 무엇을해야합니까?
내 직관은 현재 나를 향해 BufferedStreams.이것이 가야하는 방법이 있나요?
해결책
을 얻을 수 있다 예를 사용하여 작업 FileChannel.read(ByteBuffer)
하지 않기 때문에 차단 읽습니다.았다 그러나 그 아래 코드를 작동:
boolean running = true;
BufferedInputStream reader = new BufferedInputStream(new FileInputStream( "out.txt" ) );
public void run() {
while( running ) {
if( reader.available() > 0 ) {
System.out.print( (char)reader.read() );
}
else {
try {
sleep( 500 );
}
catch( InterruptedException ex ) {
running = false;
}
}
}
}
물론 동일한 것으로 일하는 타이머는 대신 스레드지만,저는 떠나는 것을 프로그래머입니다.난 아직도 더 나은 방법을 찾고 있지만,이 작품은 나를 위해 지금입니다.
아,그리고 나는 주의할 점이다:내가 사용하여 1.4.2.예 난에서 돌 나이 여전히있다.
다른 팁
하고 싶은 경우 파일을 읽는 동안에 기록되고 읽기만 새로운 콘텐츠를 다음을 달성하는 데 도움이됩니다 동일합니다.
이 프로그램을 실행하려면 당신은 그것을 실행하는 명령 프롬프트에서/터미널 창고 통과하는 파일의 이름을 읽을 수 있습니다.그것은 파일을 읽지 않으면 당신을 죽이 프로그램입니다.
java FileReader c:\myfile.txt
당신이 입력한 텍스트 행 저장한 메모장에서 당신은 텍스트가 표시됩니다에 인쇄합니다.
public class FileReader {
public static void main(String args[]) throws Exception {
if(args.length>0){
File file = new File(args[0]);
System.out.println(file.getAbsolutePath());
if(file.exists() && file.canRead()){
long fileLength = file.length();
readFile(file,0L);
while(true){
if(fileLength<file.length()){
readFile(file,fileLength);
fileLength=file.length();
}
}
}
}else{
System.out.println("no file to read");
}
}
public static void readFile(File file,Long fileLength) throws IOException {
String line = null;
BufferedReader in = new BufferedReader(new java.io.FileReader(file));
in.skip(fileLength);
while((line = in.readLine()) != null)
{
System.out.println(line);
}
in.close();
}
}
수도 있습을 살펴 java 채널에 대한 잠금의 일부입니다.
http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html
이 기능의 FileChannel
수도 시작
lock(long position, long size, boolean shared)
의 호출이 이 방법을 때까지 차단됩 지역에 잠길 수 있습니다
나는 완전히 동의 여호수아의 응답, 쓰 은 작업에 맞서 이동합니다.다음 예를 참고하십시오.
쓰 라인의 모든 150ms 에 파일을 읽는 동안,이 파일의 모든 2500ms
public class TailerTest
{
public static void main(String[] args)
{
File f = new File("/tmp/test.txt");
MyListener listener = new MyListener();
Tailer.create(f, listener, 2500);
try
{
FileOutputStream fos = new FileOutputStream(f);
int i = 0;
while (i < 200)
{
fos.write(("test" + ++i + "\n").getBytes());
Thread.sleep(150);
}
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static class MyListener extends TailerListenerAdapter
{
@Override
public void handle(String line)
{
System.out.println(line);
}
}
}
해답이 될 것으로 보인다"no"...그리고"예"입니다.이 없을 것으로 보인다 실제 방법은 알고 있으면 파일을 열어 쓰기에 대한 다른 응용 프로그램.그래서를 읽고,이러한 파일에서만 진행될 때까지는 콘텐츠가 소진되었습니다.나는 마이크의 조언을 썼 테스트 코드:
Writer.java 쓰 문자열하여 파일을 다음 기다리는 사용자에 대한 충돌하기 전에 입력 쓰기 다른 라인을 파일입니다.는 아이디어는 그것이 시작될 수 있고,그 판독기 시작될 수 있는 어떻게 대처하는"부분적인"이라는 파일에 있습니다.리더에서는 내가 쓴 Reader.java.
Writer.java
public class Writer extends Object
{
Writer () {
}
public static String[] strings =
{
"Hello World",
"Goodbye World"
};
public static void main(String[] args)
throws java.io.IOException {
java.io.PrintWriter pw =
new java.io.PrintWriter(new java.io.FileOutputStream("out.txt"), true);
for(String s : strings) {
pw.println(s);
System.in.read();
}
pw.close();
}
}
Reader.java
public class Reader extends Object
{
Reader () {
}
public static void main(String[] args)
throws Exception {
java.io.FileInputStream in = new java.io.FileInputStream("out.txt");
java.nio.channels.FileChannel fc = in.getChannel();
java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(10);
while(fc.read(bb) >= 0) {
bb.flip();
while(bb.hasRemaining()) {
System.out.println((char)bb.get());
}
bb.clear();
}
System.exit(0);
}
}
보증하지 않는 코드가 가장 좋습니다.
이 옵션을 제안해서 마이크의 정기적으로 확인이 있는 경우 새로운 데이터를 읽을 수 있는 파일에서.이때 사용자 개입이 필요한 파일을 닫고 독자가 해당된다고 판단한 경우 독서가 완성된다.또는,독자 요구를 인식할 수 있는 콘텐츠의 파일을 확인할 수 있과 끝의 쓰는 상태입니다.는 경우가 콘텐츠를 XML,이 문서 끝까지 사용할 수 있는 신호이다.
지 Java 당-se,하지만 당신은 실행할 수 있습으로 문제 있는 뭔가를 작성하는 파일이지만,그것되지 않은 실제로 아직 작성-에 있을 수도 있습니다 캐시 어딘가에,읽기 같은 파일에서 실제로 나타내지 않을 수 있습을 새롭게 정보입니다.
짧은 버전을 사용 flush()또는 어떤 관련 시스템호출을 보장하는 데이터가 실제로 파일에 기록됩니다.
참고 얘기하는 것이 아닙 OS 수준의 디스크 캐시 데이터로 얻는 여기에서 나타나야 합 read()후 이점이다.그것이 될 수 있는 언어 자체 캐시 쓰기를 기다리고 있을 때까지 버퍼을 채우거나 파일은 플러싱/닫힙니다.
가는 오픈 소스 소 Java 그래픽 꼬리를이 작업을 수행합니다.
https://stackoverflow.com/a/559146/1255493
public void run() {
try {
while (_running) {
Thread.sleep(_updateInterval);
long len = _file.length();
if (len < _filePointer) {
// Log must have been jibbled or deleted.
this.appendMessage("Log file was reset. Restarting logging from start of file.");
_filePointer = len;
}
else if (len > _filePointer) {
// File must have had something added to it!
RandomAccessFile raf = new RandomAccessFile(_file, "r");
raf.seek(_filePointer);
String line = null;
while ((line = raf.readLine()) != null) {
this.appendLine(line);
}
_filePointer = raf.getFilePointer();
raf.close();
}
}
}
catch (Exception e) {
this.appendMessage("Fatal error reading log file, log tailing has stopped.");
}
// dispose();
}
나는 그것을 시도하지 않을,하지만 당신은 테스트를 작성한 경우를 보면에서 있은 후에 결국 충돌이 일에 관계없이 여러 개 있는 경우에 작성된 데이터는 파일입니다.
는 이유 있는 사용할 수 없습니다 파이프 입력/출력 스트림?은 데이터를 쓰고 읽에서 동일한 응용 프로그램(그렇다면,당신은 데이터,당신은 왜 필요한 파일을 읽)?
그렇지 않으면,아마 읽어의 끝까지 파일,다음 모니터링을 위한 변화를 추구하는 계속...하지만 조심에 대한 경쟁 조건입니다.
을 읽을 수 없는 파일에서 열리는 다른 프로세스를 사용하여 수 fileinputstream 에,FileReader 또는 RandomAccessFile.
그러나 사용하여 FileChannel 직접 작동:
private static byte[] readSharedFile(File file) throws IOException {
byte buffer[] = new byte[(int) file.length()];
final FileChannel fc = FileChannel.open(file.toPath(), EnumSet.of(StandardOpenOption.READ));
final ByteBuffer dst = ByteBuffer.wrap(buffer);
fc.read(dst);
fc.close();
return buffer;
}