Is there a way to place a BufferedReader into a String in one shot, rather than line by line? Here is what i have so far:
BufferedReader reader = null;
try
{
reader = read(filepath);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
String line = null;
String feed = null;
try
{
line = reader.readLine();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
while (line != null)
{
//System.out.println(line);
try
{
line = reader.readLine();
feed += line;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(feed);
You could use Apache FileUtils library for the same.
Using the StringBuilder and read(char[], int, int) methods would look like this, and is probably the most optimal way to do it in Java:
final MAX_BUFFER_SIZE = 256; //Maximal size of the buffer
//StringBuilder is much better in performance when building Strings than using a simple String concatination
StringBuilder result = new StringBuilder();
//A new char buffer to store partial data
char[] buffer = new char[MAX_BUFFER_SIZE];
//Variable holding number of characters that were read in one iteration
int readChars;
//Read maximal amount of characters avialable in the stream to our buffer, and if bytes read were >0 - append the result to StringBuilder.
while ((readChars = stream.read(buffer, 0, MAX_BUFFER_SIZE)) > 0) {
result.append(buffer, 0, readChars);
}
//Convert StringBuilder to String
return result.toString();
If you know the length of your input (or an upper bound to it) you can read the whole thing to a character array, using read(char[],int,int), then use that to build a String. It doesn't matter if your third parameter (len) is greater than the size, the method will return the number of characters read.
With Guava, CharStreams.toString(reader) does the job.
Related
I have the following problem. I have create a method that read a very big textual file starting by its path.
The file is read line by line and each line is appended into a StringBuffer.
This is my code:
public void run(Vector parametri) {
if (parametri != null && (parametri.isEmpty() == false)) {
gvParam = (Vector) parametri.clone();
} else {
TraceLog.scrivi("Test Esistenza Parametri", "Parametri mancanti", false, TraceLog.lowConsole + TraceLog.highTrace + TraceLog.highLog);
target.azione("Parametri mancanti !!");
return;
}
String fattureXml = gvParam.get(0).toString();
// READ THE FILE:
StringBuffer fileContent = new StringBuffer();
try {
// Creazione del reader per leggere il file:
BufferedReader br = new BufferedReader(new FileReader(fattureXml));
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
fileContent.append(line);
}
System.out.println(fileContent.toString());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The reading section begin after the comment // READ THE FILE:
The file read seems work fine because I used this line (actually commented)
System.out.println(line);
to check the readed line and it read it correctly.
As you can see now I am adding this line to a StringBuffer (to obtain a big String representing the content of the readed file), by:
fileContent.append(line);
The problem is that, after the loop, I am trying to print in the console the content of the fileContent StringBuffer, by:
System.out.println(fileContent.toString());
but nothing is printed.
Why? What am I missing? What exactly contains the fileContent StringBuffer? Is it something like a big String containing the lines of the readed file or what?
Here's my guess: Since you're discarding all new-line characters, you end up with a single enormously long line, which your console is having troubles handling. (I've experienced this myself in the Eclipse console.)
Try changing
fileContent.append(line);
to
fileContent.append(line).append('\n');
As #assylias points out you also might want to drop Vector (and use for instance an ArrayList instead). Also, have a look at this question: Difference between StringBuilder and StringBuffer.
For future reference, the "modern" way of doing this would be
String content = new String(Files.readAllBytes(Paths.get(fileName)));
I am working on a java program that reads in XML and generates an output XML. I am having a problem replacing some of the characters in my read in file.
The following is my method:
public void readTemplateXML() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
path), "UTF8"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String line;
StringBuilder sb = new StringBuilder();
try {
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
xml = sb.toString();
xml = xml.replaceAll("<", "\\<"); //This is not working.
}
I am just outputting the "xml" string to an xml file and I am still getting "<":
<addressLine1>Main Street</addressLine1>
Is there anyway I can replace these characters with <, > ?
The encoding of the file is UTF-8.
EDIT:
the xml string is correct after the replace alls. I am using it as text content in another methods xml node:
// inner request element
Element request = doc.createElement("con:request");
request.appendChild(doc.createTextNode(xml));
rootElement.appendChild(request);
After this the content is incorrect.
Any help would be greatly appreaciated.
short answer :
Syntax:
Here is the syntax of this method:
public String replaceAll(String regex, String replacement)
Parameters:
Here is the detail of parameters:
regex -- the regular expression to which this string is to be matched.
replacement -- the string which would replace found expression.
code :
String xml="<addressLine1>Main Street</addressLine1>
";
xml = xml.replaceAll("<", "\\<");
xml = xml.replaceAll(">", "\\>");
xml = xml.replaceAll("
", "");
System.out.println( xml );
result :
<addressLine1>Main Street</addressLine1>
I was wondering how do you manipulate big Textfiles in Java, if we assume that the Filesize is larger than the memory. I googled that topic and it shows that most people recommend java.niofor such a task.
Unfortunately I haven't found any documentation on how to manipulate the File. For example read every Line, modify it, write it. I tried something like this, but this doesn't work:
FileChannel fileChannel = null;
try {
fileChannel = new RandomAccessFile(file, "rw").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(256);
while (fileChannel.read(buffer) != -1) {
buffer.rewind();
buffer.flip();
String nextLine = buffer.asCharBuffer().toString();
if (replaceBackSlashes) {
nextLine = nextLine.replace("\\\\", "/");
}
if (!(removeEmptyLines && StringUtils.isEmpty(nextLine))) {
buffer.flip();
buffer.asCharBuffer().put(nextLine);
}
buffer.clear();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fileChannel != null) {
try {
fileChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So what are your recommendations? Also the String nextline, doesn't match anything in my File. Maybe I need to set the encoding?
Line by line. Something like this ...
public static void main(String[] args) throws Exception {
File someFile = new File("someFile.txt");
File temp = File.createTempFile(someFile.getName(), null);
BufferedReader reader = null;
PrintStream writer = null;
try {
reader = new BufferedReader(new FileReader(someFile));
writer = new PrintStream(temp);
String line;
while ((line = reader.readLine())!=null) {
// manipulate line
writer.println(line);
}
}
finally {
if (writer!=null) writer.close();
if (reader!=null) reader.close();
}
if (!someFile.delete()) throw new Exception("Failed to remove " + someFile.getName());
if (!temp.renameTo(someFile)) throw new Exception("Failed to replace " + someFile.getName());
}
Kudos to xagyg for a nice, clean answer! The following just didn't fit into a comment:
If you're running Java 7 already, you can save a lot of boilerplate code by using try-with-resources for the processing loop:
File source = ...
File target = ...
try (BufferedReader in = new BufferedReader(new FileReader(source));
PrintStream out = new PrintStream(target)) {
String line;
while ((line = in.readLine()) != null) {
// manipulate line
out.println(line);
}
}
// no catch or finally clause!
No more of that initalize-to-null-try-catch-finally-close-if-not-null mess, Java will take care of that for you now. Less code, less potential to forget or screw up that crucial call to close().
I am trying to use setText, and I want to use a String array. First, I create a String [], then I assign data to String[0], then I want to .setText(String[0]) on my TextView, is this the right way?
Note : I'm using a StringTokenizer to split Strings in the textfile
try {
filename = "myk.txt";
FileReader filereader = new FileReader(Environment.getExternalStorageDirectory() + "/Q/" + filename);
BufferedReader bufferedreader = new BufferedReader(filereader);
try {
while ((text = bufferedreader.readLine()) != null){
sb.append(text);
sb.toString().split(";");
tokens = new StringTokenizer(sb.toString(), ";");
///NULLPOINTER EXEPTION HERE//// if (tokens.countTokens() > 0){questionfromfile[0] = tokens.nextToken();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
////ETC ...//// and now textview.setText(question[0]);
Sure, you mean something like
String[] strings = new String [5];
strings[0] = "foobar";
component.setText(strings[0]);
why do you have this line:
sb.toString().split(";");
?
are you forgetting that a string is immutable ,meaning that using the standard API that you use , the string will never change itself , but create new objects instead?
about StringTokenizer, as javadocs say:
StringTokenizer is a legacy class that is retained for compatibility
reasons although its use is discouraged in new code. It is recommended
that anyone seeking this functionality use the split method of String
or the java.util.regex package instead.
I have a method for my app to read a random line from a text file and return it. Im using the randTxt() to read and return a random line from the txt file.
but it only shows the same line (1st line) everytime.
public String randTxt(){
// Read in the file into a list of strings
InputStreamReader inputStream = new InputStreamReader(getResources().openRawResource(R.raw.randomstuff));
//ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String theLine="";
int i;
try {
i = inputStream.read();
while (i != -1) {
i = inputStream.read();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LineNumberReader rdr = new LineNumberReader(inputStream);
int numLines = 30;
Random r = new Random();
rdr.setLineNumber(r.nextInt(numLines));
try {
theLine = rdr.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return theLine;
}
How can I fix it? and Can someone explain what's wrong in my code?
Here's the framework for doing what you need using BufferedReader. In this case, you don't need to store the values in a temp array.
InputStreamReader inputStream = new InputStreamReader
(getResources().openRawResource(R.raw.randomstuff));
BufferedReader br = new BufferedReader(inputStream);
int numLines = 30;
Random r = new Random();
int desiredLine = r.nextInt(numLines);
String theLine="";
int lineCtr = 0;
while ((theLine = br.readLine()) != null) {
if (lineCtr == desiredLine) {
break;
}
lineCtr++;
}
...
Log.d(TAG, "Magic line is: " +theLine);
You have gotten an answer of how to fix your code, but no explanation of why our original code did not work.
LineNumberReader.setLineNumber(int) does not go to the actual line, it just changes what number you call the current line.
So, say you read two lines, getLineNumber() will now return 2 (it started at 0 and increased by 1 each time a newline was encountered). if you now setLineNumber(10), getLineNumber() will return 10. Reading yet another line (your third) will cause getLineNumber() to return 11.
This is described in the Java Doc.
inputStream.read does not return a line number. it returns the byte that was read. this isn't how you would read line by line. to read line by line, you should use buffered reader's readLine method. its probably easier at that point to read it all into a local array and use that array to randomly get an entry, rather than using a line number reader.
I think Random() function returns a value between 0 and 1. hence, you may have to multiply it with 100 to get an integer value. May even consider a MOD "your upper limit" operation to guarentee that the index you finally get is between 0 and your upper limit
Use the index you calculated thus, in your setLineNumber() method.
Edit:
As john said, we can get whole number using Random() object.
public String getRandomLine(String fileLoc) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(fileLoc));
ArrayList<String> lines = new ArrayList<String>();
String line =null;
while( (line = reader.readLine())!= null )
lines.add(line);
// Choose a random one from the list
return lines.get(new Random().nextInt(lines.size()));
}
public String getRandomLineOpt(String fileLoc)throws IOException
{
File f=new File(fileLoc);
RandomAccessFile rcf=new RandomAccessFile(f, "r");
long rand = (long)(new Random().nextDouble()*f.length());
rcf.seek(rand);
rcf.readLine();
return rcf.readLine();
}