I need to copy a line from a file to another depending on condition
this is my code
import org.apache.commons.io.FileUtils;
public class FileCopy {
public static void main(String args[]) throws IOException {
File source = \\
File fileToCopyFrom \\
File target :\\
if (!target.exists()) {
target.createNewFile();
}
PrintStream fstream =new PrintStream(target);
BufferedReader brSource = new BufferedReader(new FileReader(source));
BufferedReader brFileToCopyFrom = new BufferedReader(new FileReader(fileToCopyFrom));
String lineSource;
String lineToCopy;
while((lineSource = brSource.readLine()) != null) {
while ((lineToCopy=brFileToCopyFrom.readLine())!=null) {
if (lineToCopy.contains(lineSource.substring(lineSource.indexOf("_")+1, lineSource.indexOf(".")-1)))
fstream.println(lineToCopy);
}
}
}}
but it copy only the first line
where is the error?
Only the first is copied because in the second iteration of the first while the brFileToCopyFrom is reached the end of file.
You need to open the BufferedReader brFileToCopy inside the first while (example 1) or use a mark/reset feature (example 2).
Example 1:
while ((lineSource = brSource.readLine()) != null) {
BufferedReader brFileToCopyFrom = new BufferedReader(new FileReader(fileToCopyFrom));
while ((lineToCopy = brFileToCopyFrom.readLine()) != null) {
...
}
}
}
Example 2:
brFileToCopyFrom.mark(1024); // number of characters to be read while preserving the mark
while ((lineSource = brSource.readLine()) != null) {
brFileToCopyFrom.reset();
while ((lineToCopy = brFileToCopyFrom.readLine()) != null) {
...
}
}
}
I suggest to use commons-io.jar. In this FileUtils class lot of methods to do File operation like copy, move and remove.
EDIT
try with below if conndition which contains break.
while ((lineSource = brSource.readLine()) != null) {
while ((lineToCopy = brFileToCopyFrom.readLine()) != null) {
if (lineToCopy.contains(lineSource.substring(
lineSource.indexOf("_") + 1,
lineSource.indexOf(".") - 1))) {
fstream.println(lineToCopy);
break;
}
}
}
you create your stream, you read all enntries from your stream, for first line, but when you want to do this for second line brFileToCopyFrom is empty (you already took everything from it when you were checking your first line.
so what you could do is move creating your brFileToCopyFrom to the loop,
while((lineSource = brSource.readLine()) != null) {
BufferedReader brFileToCopyFrom = new BufferedReader(new FileReader(fileToCopyFrom));
...
that should works
Related
I would like know how I can remove a blank line while reading/writing a file?
for(int i=1;i<=count;i++) {
FileInputStream fistream1;
try {
name1="file1"+Integer.toString(i)+".txt";
fistream1 = new FileInputStream(name1); // first source file
fistream2 = new FileInputStream("Result.txt"); //second source file
sistream = new SequenceInputStream(fistream2, fistream1);
fostream= new PrintWriter(new BufferedWriter(new FileWriter( result+".txt", true)));
while( ( temp = sistream.read() ) != -1) {
fostream.write(temp); // to write to file
}
fostream.println("");
fostream.close();
sistream.close();
fistream1.close();
fistream2.close();
}
I found this code but I couldn't implement it because of following line:
String line;
while((line = br.readLine())!= null) { ... }
They have used line as a String, but in my case I have temp as int:
int temp;
while((temp = sistream.read())!=-1) { ... }
Is there a way to solve this problem?
The answer of #Abdelhak is not acceptable.
You can try something like this:
while( ( temp = sistream.read() ) != -1) {
if (!temp.trim().equals(""))
{
fostream.write(temp); // to write to file
}
...
The solution was so simple.
I should read lines instead of reading bytes to determine if a line is empty and used a BufferedReader on conjunction with SequenceInputStream.
I'm trying to write a program, which reads text from a file that is specified by the user. Now, this program should detect an empty line.
This is what I have unsuccessfully tried:
public static void editFile(String filePath) throws FileNotFoundException, IOException {
file = new File(filePath);
if(file.exists()) {
fileRead = new FileReader(file);
bufferedReader = new BufferedReader(fileRead);
String line = bufferedReader.readLine();
System.out.println(line);
while(line != null) {
line = bufferedReader.readLine();
if(line == "") {
//line = null;
System.out.println("a");
}
System.out.println(line);
}
}
}
To be more clear:
If I'm passing in a text file with for example this text:
test1
test2
test3
test4
it should print 2 a's in the console because of the empty spaces, but it doesn't.
Thank you for your time, I am glad for any suggestion you may have.
This is because the comparison is wrong. You can't use == to compare two strings, you need to use the equals method:
if(line.equals(""))
Since you are checking for empty string, you can also write
if(line.isEmpty())
How do I compare strings in java?
BackSlash is entirely correct, and has answered your question. I'd like to add that your code has some errors:
You're not closing the Reader
You're not testing the first line for blank
You're processing the null value when reaching EOF
The following corrects these errors.
public static void editFile(String filePath) throws IOException
{
File file = new File(filePath);
if (file.exists())
{
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
try
{
String line;
while ((line = bufferedReader.readLine()) != null)
{
if (line.isEmpty())
{
//line = null;
System.out.println("a");
}
System.out.println(line);
}
} finally {
bufferedReader.close();
}
}
}
Output is:
test1
test2
a
test3
a
test4
Note: You're still printing the blank line in addition to the "a".
What you're doing wrong is that you're comparing the variable itself, not its value with a null string.
Generally there are built-in functions in the string class that return true & false for checking if it's == with something.
if(line.equals("")) { ... }
Or you can just use any alternative way.
I am trying to replace a string from a js file which have content like this
........
minimumSupportedVersion: '1.1.0',
........
now 'm trying to replace the 1.1.0 with 1.1.1. My code is searching the text but not replacing. Can anyone help me with this. Thanks in advance.
public class replacestring {
public static void main(String[] args)throws Exception
{
try{
FileReader fr = new FileReader("G:/backup/default0/default.js");
BufferedReader br = new BufferedReader(fr);
String line;
while((line=br.readLine()) != null) {
if(line.contains("1.1.0"))
{
System.out.println("searched");
line.replace("1.1.0","1.1.1");
System.out.println("String replaced");
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
First, make sure you are assigning the result of the replace to something, otherwise it's lost, remember, String is immutable, it can't be changed...
line = line.replace("1.1.0","1.1.1");
Second, you will need to write the changes back to some file. I'd recommend that you create a temporary file, to which you can write each `line and when finished, delete the original file and rename the temporary file back into its place
Something like...
File original = new File("G:/backup/default0/default.js");
File tmp = new File("G:/backup/default0/tmpdefault.js");
boolean replace = false;
try (FileReader fr = new FileReader(original);
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(tmp);
BufferedWriter bw = new BufferedWriter(fw)) {
String line = null;
while ((line = br.readLine()) != null) {
if (line.contains("1.1.0")) {
System.out.println("searched");
line = line.replace("1.1.0", "1.1.1");
bw.write(line);
bw.newLine();
System.out.println("String replaced");
}
}
replace = true;
} catch (Exception e) {
e.printStackTrace();
}
// Doing this here because I want the files to be closed!
if (replace) {
if (original.delete()) {
if (tmp.renameTo(original)) {
System.out.println("File was updated successfully");
} else {
System.err.println("Failed to rename " + tmp + " to " + original);
}
} else {
System.err.println("Failed to delete " + original);
}
}
for example.
You may also like to take a look at The try-with-resources Statement and make sure you are managing your resources properly
If you're working with Java 7 or above, use the new File I/O API (aka NIO) as
// Get the file path
Path jsFile = Paths.get("C:\\Users\\UserName\\Desktop\\file.js");
// Read all the contents
byte[] content = Files.readAllBytes(jsFile);
// Create a buffer
StringBuilder buffer = new StringBuilder(
new String(content, StandardCharsets.UTF_8)
);
// Search for version code
int pos = buffer.indexOf("1.1.0");
if (pos != -1) {
// Replace if found
buffer.replace(pos, pos + 5, "1.1.1");
// Overwrite with new contents
Files.write(jsFile,
buffer.toString().getBytes(StandardCharsets.UTF_8),
StandardOpenOption.TRUNCATE_EXISTING);
}
I'm assuming your script file size doesn't cross into MBs; use buffered I/O classes otherwise.
I've got a JUnit test that tests a piece of code I've been working on that uses temporary files to perform certain functions. For whatever reason, the test passes on OSX, but fails on Windows 7. To simplify things, I copied the test into a new file, and boiled it down to be as simple as possible while still demonstrating the error.
Basically, I initialize the temporary file by writing a comma separated key-value pair into the file (and then assert that it exists, which it does). Then, I attempt to replace the value of the line, based on the key. updateValueForKey() has the boolean "checkOldVal", which, if true, requires that oldVal passed in match the one in the file. This test fails on Windows, and passes on OSX whether this is true or false
Windows Java version: 1.6.0_45
OSX Java version: 1.6.0_65
The code is as follows:
public class SimpleTempFileTest {
ReadWriteLock _fileLock = null;
File _file = null;
public SimpleTempFileTest() {
}
#Test
public void simpleTempFileTest() throws Exception {
_file = File.createTempFile("testCsv", null);
_file.deleteOnExit();
_fileLock = new ReentrantReadWriteLock();
BufferedWriter writer = null;
try {
_fileLock.writeLock().lock();
writer = new BufferedWriter(new FileWriter(_file, true));
writer.append("foo,bar");
writer.newLine();
} finally {
if (writer != null) {
writer.close();
}
_fileLock.writeLock().unlock();
}
BufferedReader br = new BufferedReader(new FileReader(_file));
String line = br.readLine();
assertTrue("Unexpected value. Line=" + line, line.equals("foo,bar"));
assertTrue("Unexpected value. Line=" + line, br.readLine() == null);
br.close();
//Fails whether checkOldVal is true or false
updateValueForKey("foo", "bar", "baz", true);
br = new BufferedReader(new FileReader(_file));
line = br.readLine();
//Everything up to this point passes, but the following assertion fails
assertTrue("Unexpected value. Line=" + line, line.equals("foo,baz"));
assertTrue("Unexpected value. Line=" + line, br.readLine() == null);
br.close();
}
String updateValueForKey(String key, String oldVal, String newVal, boolean checkOldVal) throws FileNotFoundException, IOException {
BufferedReader br = null;
BufferedWriter writer = null;
File temp = null;
try {
_fileLock.writeLock().lock();
br = new BufferedReader(new FileReader(_file));
temp = File.createTempFile("csvTmp", ".tmp");
writer = new BufferedWriter(new FileWriter(temp, true));
boolean seek = true;
String line;
while ((line = br.readLine()) != null) {
if (seek) {
String[] nvp = line.split(",");
System.out.println("nvp[0]=" + nvp[0] + ", nvp[1]=" + nvp[1]);
if (nvp[0].equalsIgnoreCase(key)) {
if (nvp[1].equals(oldVal) || !checkOldVal) {
String lineToWrite = key + "," + newVal;
System.out.println("Writing " + lineToWrite);
writer.write(lineToWrite);
writer.newLine();
seek = false;
continue;
} else {
System.out.println("Failed for " + key + ". Val incorrect.");
return "Password incorrect";
}
}
}
writer.write(line);
writer.newLine();
}
_file.delete();
temp.renameTo(_file);
return null;
} finally {
if (br != null) {
br.close();
}
if (writer != null) {
writer.close();
}
if (temp != null) {
temp.delete();
}
_fileLock.writeLock().unlock();
}
}
}
Any ideas guys? Thanks.
The issue is related to differences between the way Windows and Unix handle locks on files. On Unix, One process can be writing to a file, and another can open it to read it. Windows does not allow this.
Full disclosure: I expected Java to throw an IOException if it failed to perform IO-type stuff on files, briefly forgetting that many of those operations return boolean specifying whether or not the operation was successful.
Long story short, near the end of updateValueForKey(), where I delete _file, and rename tmp to _file, temp still has a FileWriter open against it, and _file still has a BufferedReader open against it. Basically, I had to move the _file.delete and temp.renameTo() below the finally block.
BufferedReader in;
String line;
while ((line = in.readLine() != null) {
processor.doStuffWith(line);
}
This is how I would process a file line-by-line. In this case, however, I want to send two lines of text to the processor in every iteration. (The text file I'm processing essentially stores one record on two lines, so I'm sending a single record to the processor each time.)
What's the best way of doing this in Java?
Why not just read two lines?
BufferedReader in;
String line;
while ((line = in.readLine() != null) {
processor.doStuffWith(line, in.readLine());
}
This assumes that you can rely on having full 2-line data sets in your input file.
BufferedReader in;
String line1, line2;
while((line1 = in.readLine()) != null
&& (line2 = in.readLine()) != null))
{
processor.doStuffWith(line1, line2);
}
Or you could concatenate them if you wanted.
I would refactor code to look somehow like this:
RecordReader recordReader;
Processor processor;
public void processRecords() {
Record record;
while ((record = recordReader.readRecord()) != null) {
processor.processRecord(record);
}
}
Of course in that case you have to somehow inject correct record reader in to this class but that should not be a problem.
One implementation of the RecordReader could look like this:
class BufferedRecordReader implements RecordReader
{
BufferedReader in = null;
BufferedRecordReader(BufferedReader in)
{
this.in = in;
}
public Record readRecord()
{
String line = in.readLine();
if (line == null) {
return null;
}
Record r = new Record(line, in.readLine());
return r;
}
}