Basic explanation:
I'm coding a simple java utility which will take xml file and convert it into html. All xml files have same structure and need to be converted into same looking HTML file so i chose to code it using BufferedReader and Writer, see code below.
I'm having following problem If i'm using file that is on local disk, than there is no problem and everything workes fine, but when i try to use file that is on connected shared network disk, code throws exception.
this is whole code
reading and writting file that is stored in project folder workes just fine and just as i want to, i'm only having problem with file stored on network disk.
public static void main(String[] args) {
String cestaKsuboruXml = "file.xml"; //workes fine
//this one throws error
// String cestaKsuboruXml = "\\172.27.20.38\eDesk\2017\0925\144f7d8d-3786-4858-95ef-bb853c41b713\1_PridelenieCislaPodania.xml";
//class which contains html code
sablonaJedna sablonaJedna = new sablonaJedna();
String fileName = null ;
String line = null;
StringBuilder text = new StringBuilder();
StringBuilder subject = new StringBuilder();
try {
FileReader fileReader = new FileReader(cestaKsuboruXml);
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(new FileInputStream(cestaKsuboruXml), "UTF-8"));
while ((line = bufferedReader.readLine()) != null) {
if (line.contains("<subject>")) {
subject.append(line);
}
if (!line.contains("<GeneralAgenda") && !line.contains("<subject>"))
{
text.append(line);
}
}
} catch (IOException ex) {
System.out.println("Exception");
}
String text2 = text.toString();
String subject2 = subject.toString();
subject2 = subject2.replace("<subject>", "");
subject2 = subject2.replace("</subject>", "");
text2 = text2.replace("<text>", "");
text2 = text2.replace("</text>", "");
text2 = text2.replace("</GeneralAgenda>", "");
try {
BufferedWriter writer = new BufferedWriter
(new OutputStreamWriter(new FileOutputStream("vvvaa.html", true), "UTF-8"));
writer.write(sablonaJedna.getSablonaCss() + sablonaJedna.getSablonaHtml() + subject2 +
"</span></div><div class=\"clear\"> </div><div><label class=\"labelVis\">Text: </label> <span class=\"contentVis wordwrap\">"
+ text2 + "</span></div><div class=\"clear\"> </div></div></div></body></html>"
);
writer.close();
} catch (IOException xx) {
System.out.println("Exception");
}
}
all i had to do was use this as a source:
String cestaKsuboruXml = "\\\\172.27.20.38\\eDesk\\2017\\0925\\144f7d8d-3786-4858-95ef-bb853c41b713\\1_PridelenieCislaPodania.xml";
so two more backslashes at the start of a link
Related
I am new to java and working on file operations. I have this input and modify text files as follows:
input.txt: contains id,firstname,lastname
1000:Mark,Peters,3.9
modify.txt: contains id,oldvalue:newvalue
1000,Mark:John
I am supposed to search the id and make the updations accordingly. So in modify.txt file I have an id and old value which is to be replaced with new value in the input.txt
So after modification, my input.txt line output should be printed as:
1000:John,Peters,3.9
I have written the following code, but I am not sure how to proceed with updations. However, I have managed to read the files and split it and get the id.
public static void main(String[] args) {
try {
BufferedReader file1 = new BufferedReader(new FileReader(new File("src/input.txt")));
BufferedReader file2 = new BufferedReader(new FileReader(new File("src/modify.txt")));
String str1 = file1.readLine();
String input[] = str1.split(":");
int id1 = Integer.parseInt(input[0]);
System.out.println(str1);
System.out.println(id1);
String str2 = file2.readLine();
String modify[] = str2.split(",");
int id2 = Integer.parseInt(modify[0]);
System.out.println(str2);
System.out.println(id2);
file1.close();
file2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Can anyone help me with this? Thanks. Appreciate your help.
You can read the line in modify.txt file and split the line using regex [,:]. It will split the line into separate parts like id, firstName and lastName etc.
After read the each line in input.txt file and and split the each line using the regex [,:]. And compare the first element in the list with element in the list created from modify.txt file. if the element is equals replace the line with the new data from list created from modify.txt file.
public static void main(String[] args) {
try {
BufferedReader f1 = new BufferedReader(new FileReader(new File("src/input.txt")));
BufferedReader f2 = new BufferedReader(new FileReader(new File("src/modify.txt")));
String regex = "[,:]";
StringBuffer inputBuffer = new StringBuffer();
String line;
String[] newLine = f2.readLine().split(regex);
while ((line = f1.readLine()) != null) {
String[] data = line.split(regex);
if (data[0].equals(newLine[0])) {
line = line.replace(newLine[1], newLine[2]);
}
inputBuffer.append(line);
inputBuffer.append(System.lineSeparator());
}
f1.close();
f2.close();
FileOutputStream fileOut = new FileOutputStream("src/input.txt");
fileOut.write(inputBuffer.toString().getBytes());
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
While creating a method to my class, I got an unexpected problem. I've tried solutions from other theards, but they just don't work for me. My method should simply find the line specified, copy the file skipping unnecessary line, delete the original file and rename temporary file to the name of original file. It succesfuly creates new file as expected, but then fails to delete previous one as it fails to rename temporary file to original. I can't figure out, why?
void lineDelete(String file_name, String line_to_erase){
try {
int line_number = 0;
String newline = System.getProperty("line.separator");
File temp = new File("temporary.txt");
File theFile = new File(file_name+".txt");
String path = theFile.getCanonicalPath();
File filePath = new File(path);
BufferedReader reader = new BufferedReader(new FileReader(file_name + ".txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
String lineToRemove = line_to_erase;
String currentLine;
while((currentLine = reader.readLine()) != null) {
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine + newline));
}
writer.close();
reader.close();
filePath.delete();
temp.renameTo(theFile);
}
catch (FileNotFoundException e){
System.out.println(e);
}
catch (IOException e){
System.out.println(e);
}
Try this code:
void lineDelete(String file_name, String line_to_erase){
try {
int line_number = 0;
String newline = System.getProperty("line.separator");
File temp = new File("temporary.txt");
File theFile = new File(file_name+".txt");
String path = theFile.getCanonicalPath();
BufferedReader reader = new BufferedReader(new FileReader(theFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
String lineToRemove = line_to_erase;
String currentLine;
while((currentLine = reader.readLine()) != null) {
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine + newline));
}
writer.close();
reader.close();
theFile.delete();
temp.renameTo(file_name + ".txt");
}
catch (FileNotFoundException e){
System.out.println(e);
}
catch (IOException e){
System.out.println(e);
}
I could suggest a couple of reasons why the delete and/or rename might fail, but there is a better way to solve your problem than guessing1.
If you use Path and the Files.delete(Path) and Files.move(Path, Path, CopyOption...) methods, they will throw exceptions if the operations fail. The exception name and message should give you clues as to what is actually going wrong.
The javadoc is here and here.
1 - Here are a couple of guesses: 1) the file has been opened elsewhere, and it is locked as a result. 2) You don't have access to delete the file.
I have tried doing it like this:
import java.io.*;
public class ConvertChar {
public static void main(String args[]) {
Long now = System.nanoTime();
String nomCompletFichier = "C:\\Users\\aahamed\\Desktop\\test\\test.xml";
Convert(nomCompletFichier);
Long inter = System.nanoTime() - now;
System.out.println(inter);
}
public static void Convert(String nomCompletFichier) {
FileWriter writer = null;
BufferedReader reader = null;
try {
File file = new File(nomCompletFichier);
reader = new BufferedReader(new FileReader(file));
String oldtext = "";
while (reader.ready()) {
oldtext += reader.readLine() + "\n";
}
reader.close();
// replace a word in a file
// String newtext = oldtext.replaceAll("drink", "Love");
// To replace a line in a file
String newtext = oldtext.replaceAll("&(?!amp;)", "&");
writer = new FileWriter(file);
writer.write(newtext);
writer.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
However the code above takes more time to execute than creating two different files:
import java.io.*;
public class ConvertChar {
public static void main(String args[]) {
Long now = System.nanoTime();
String nomCompletFichier = "C:\\Users\\aahamed\\Desktop\\test\\test.xml";
Convert(nomCompletFichier);
Long inter = System.nanoTime() - now;
System.out.println(inter);
}
private static void Convert(String nomCompletFichier) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
File file = new File(nomCompletFichier);
File tempFile = File.createTempFile("buffer", ".tmp");
bw = new BufferedWriter(new FileWriter(tempFile, true));
br = new BufferedReader(new FileReader(file));
while (br.ready()) {
bw.write(br.readLine().replaceAll("&(?!amp;)", "&") + "\n");
}
bw.close();
br.close();
file.delete();
tempFile.renameTo(file);
} catch (IOException e) {
// writeLog("Erreur lors de la conversion des caractères : " + e.getMessage(), 0);
} finally {
try {
bw.close();
} catch (Exception ignore) {
}
try {
br.close();
} catch (Exception ignore) {
}
}
}
}
Is there any way to do the 2nd code without creating a temp file and reducing the execution time? I am doing a code optimization.
The main reason why your first program is slow is probably that it's building up the string oldtext incrementally. The problem with that is that each time you add another line to it it may need to make a copy of it. Since each copy takes time roughly proportional to the length of the string being copied, your execution time will scale like the square of the size of your input file.
You can check whether this is your problem by trying with files of different lengths and seeing how the runtime depends on the file size.
If so, one easy way to get around the problem is Java's StringBuilder class which is intended for exactly this task: building up a large string incrementally.
The main culprit in your first example is that you're building oldtext inefficiently using String concatenations, as explained here. This allocates a new string for every concatenation. Java provides you StringBuilder for building strings:
StringBuilder builder = new StringBuilder;
while(reader.ready()){
builder.append(reader.readLine());
builder.append("\n");
}
String oldtext = builder.toString();
You can also do the replacement when you're building your text in StringBuilder. Another problem with your code is that you shouldn't use ready() to check if there is some content left in the file - check the result of readLine(). Finally, closing the stream should be in a finally or try-with-resources block. The result could look like this:
StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line = reader.readLine();
while (line != null) {
builder.append(line.replaceAll("&(?!amp;)", "&"));
builder.append('\n');
line = reader.readLine();
}
}
String newText = builder.toString();
Writing to a temporary file is a good solution too, though. The amount of I/O, which is the slowest to handle, is the same in both cases - read the full content once, write result once.
public static void doubleSpace(String fileName) {
try {
FileReader reader = new FileReader(fileName);
Scanner in = new Scanner(reader);
String outputFileName = fileName.charAt(0) + ".ds";
PrintWriter pOut = new PrintWriter(outputFileName);
// Opening of files for input and output
while (in.hasNextLine()) {
String line = in.nextLine();
pOut.println(line + "\n");
pOut.print("\n");
// System.out.println(line + "\n"); //Test
}
pOut.close(); // Close the files if they have been opened.
} catch (Exception e) {
}
}
So basically my input file contains
a
b
c
and my output file should look like
a
b
c
However, my output file always contains only abc.
Any help would be much appreciated!
Use a BufferedWriter. It has a .newLine() method. This method will use the platform's default line separator.
And use a BufferedReader. It has a .readLine() method.
Example:
// NOTE: you should really be using UTF-8
final Charset charset = Charset.defaultCharset();
final Path src = Paths.get(filename);
final Path dst = Paths.get(filename + ".ds");
String line;
try (
final BufferedReader reader = Files.newBufferedReader(src, charset);
final BufferedWriter writer = Files.newBufferedWriter(dst, charset);
) {
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
writer.newLine();
}
}
You are likely useing the wrong character(s) for new line for your plattform. Use
System.getProperty("line.separator");
to get the right value.
I need to load from text file text which I will be replacing in other string.
For example I have text file:
\n;(br)
After loading this file I need to change all break lines to (br) so I will receive one line string.
Problems is when I'm loading text from file - I don't get string \n;(br) but \\n;(br)
Anyone know how to do that?
My code - I know that I'm adding '\n' in method applyFilters but it is because that there can be situation when I don't whant to change that.
void loadSource(){
File file = new File(sourcePath);
BufferedReader reader=null;
String text;
try{
reader = new BufferedReader( new FileReader(file));
}catch(FileNotFoundException e){
e.printStackTrace();
}
try{
while((text = reader.readLine()) != null){
sourceText.add(text);
}
}catch(Exception e){
e.printStackTrace();
}
}
void loadFilters(){
File file = new File(filterPath);
BufferedReader reader=null;
String text;
try{
reader = new BufferedReader( new FileReader(file));
}catch(FileNotFoundException e){
System.out.println("Błąd, brak pliku źródłowego");
e.printStackTrace();
}
try{
while((text = reader.readLine()) != null){
filterText.add(text);
}
}catch(Exception e){
e.printStackTrace();
}
}
void applyFilters(){
for (String s : sourceText){
finalText = finalText+ s + "\n";
}
for(String filter : filterText)
{
finalText = finalText.replace(filter.split(";")[0],filter.split(";")[1]);
}
System.out.println(finalText);
}
It sounds like you want the "\n" in your text file to represent a newline character rather than a backslash followed by an n. Have a look at this question:
How to unescape a Java string literal in Java?