使用单独的线程在java中读取和写入文件

我创建了两个线程并修改了run函数,以便一个线程读取一行,另一个线程将同一行写入新文件。 这种情况发生,直到整个文件被复制。 我得到的问题是,即使我已经使用变量来控制线程逐个执行但仍然线程执行不均匀,即一个线程执行多次然后控件传输。 我附加代码的任何解决方案。 我是java新手,因为它只用于类分配,所以代码可能不是最优化的。

public class thread1 extends Thread { //To create producer and consumer as threads //Shared variable public static int x = 0;//checks if all lines are read public static String line; /holds lines from file public static int j = 0;//variable to switch between threads based upon its value public thread1(String threadName) { //Constuctor super(threadName); //Call to constructor of Thread class } public void run() { while (x != -1) { if (Thread.currentThread().getName().contains("Reader")) { if (x != -1&&j==0) { j=1; String fileName = "d:/salfar.txt"; try { // FileReader reads text files in the default encoding. FileReader fileReader = new FileReader(fileName); // Always wrap FileReader in BufferedReader. BufferedReader bufferedReader = new BufferedReader(fileReader); for (int check = 0; check <= x; check++) { line = bufferedReader.readLine(); } if (line == null) { x = -1; } else { System.out.println(line); x++; } // Always close files. bufferedReader.close(); } catch (FileNotFoundException ex) { System.out.println( "Unable to open file '" + fileName + "'"); } catch (IOException ex) { System.out.println( "Error reading file '" + fileName + "'"); // Or we could just do this: // ex.printStackTrace(); } } yield(); } else if (Thread.currentThread().getName().contains("writer")) { if (x != -1 && line != null&&j==1) { j=0; String fileName = "d:/salfar1.txt"; try { // Assume default encoding. FileWriter fileWriter = new FileWriter(fileName, true); // Always wrap FileWriter in BufferedWriter. BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); // Note that write() does not automatically // append a newline character. bufferedWriter.write(line); bufferedWriter.newLine(); System.out.println("y"); // Always close files. bufferedWriter.close(); } catch (IOException ex) { System.out.println( "Error writing to file '" + fileName + "'"); // Or we could just do this: // ex.printStackTrace(); } } Thread.yield(); } else{} } } public static void main(String[] args) { thread1 p = new thread1("Reader"); thread1 c = new thread1("writer"); p.start(); c.start(); } } Thanks 

您无法控制线程执行的顺序。 但是,要通过单独的线程执行读写操作,您应该使用具有以下属性的BlockingQueue:

一个队列,它还支持在检索元素时等待队列变为非空的操作,并在存储元素时等待队列中的空间可用。

ReaderThread将从输入文件中读取。

 import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.concurrent.BlockingQueue; public class ReaderThread implements Runnable{ protected BlockingQueue blockingQueue = null; public ReaderThread(BlockingQueue blockingQueue){ this.blockingQueue = blockingQueue; } @Override public void run() { BufferedReader br = null; try { br = new BufferedReader(new FileReader(new File("./inputFile.txt"))); String buffer =null; while((buffer=br.readLine())!=null){ blockingQueue.put(buffer); } blockingQueue.put("EOF"); //When end of file has been reached } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch(InterruptedException e){ }finally{ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } 

WriterThread将写入输出文件。

 import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.concurrent.BlockingQueue; public class WriterThread implements Runnable{ protected BlockingQueue blockingQueue = null; public WriterThread(BlockingQueue blockingQueue){ this.blockingQueue = blockingQueue; } @Override public void run() { PrintWriter writer = null; try { writer = new PrintWriter(new File("outputFile.txt")); while(true){ String buffer = blockingQueue.take(); //Check whether end of file has been reached if(buffer.equals("EOF")){ break; } writer.println(buffer); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch(InterruptedException e){ }finally{ writer.close(); } } } 

从Launcher类开始你的multithreading读写。

 import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class Launcher { public static void main(String[] args) { BlockingQueue queue = new ArrayBlockingQueue(1024); ReaderThread reader = new ReaderThread(queue); WriterThread writer = new WriterThread(queue); new Thread(reader).start(); new Thread(writer).start(); } } 

这是我的解决方案。 我的想法是使用我们的线程将读取和写入的实际文件名。 我们需要确保只有一个问题,即没有两个线程试图在同一个文件上运行。 解决方法是在run方法中简单地使用同步代码块。

我们必须记住,字符串在Java中是不可变的。 考虑以下:

 String s1 = "test.txt"; String s2 = "test.txt"; 

现在,我们必须问自己如何jvm重用不可变的“test.txt”。 在这种情况下,s1和s2 String对象都指向相同的“test.txt”。

理解这个概念对我们来说也是有用的:

 public class Client { public static void main( String args [] ) { String filename = "test.txt"; String filename2 = "test.txt"; Reader reader = new Reader( filename ) ; Writer writer = new Writer( filename2 ) ; while(true) { reader.run(); writer.run(); } } } public class Writer implements Runnable { public String filename; public Writer( String filename ) { this.filename = filename; } @Override public void run() { synchronized( this.filename ) { System.out.println( "writing to a file:" + this.filename ); } } } public class Reader implements Runnable { public String filename; public Reader( String filename ) { this.filename = filename; } @Override public void run() { synchronized( this.filename ) { System.out.println( "reading a file:" + this.filename ); } } }