tags:

views:

454

answers:

5

I have read a file into a String. The file contains various names, one name perline. Now the problem is that I want those names in a String array.

For that I have written the following code:

String [] names = fileString.split("\n"); // fileString is the string representation of the file

But I am not getting the desired results and the array obtained after splitting the string is of length 1. It means that the "fileString" doesn't have "\n" character but the file has this "\n" character.

So How to get around this problem?

+3  A: 

The problem is not with how you're splitting the string; that bit is correct.

You have to review how you are reading the file to the string. You need something like this:

private String readFileAsString(String filePath) throws IOException {
        StringBuffer fileData = new StringBuffer();
        BufferedReader reader = new BufferedReader(
                new FileReader(filePath));
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
        }
        reader.close();
        return fileData.toString();
    }
Bruno Rothgiesser
While correct I have a word of warning for anyone who sees this: I wouldn't use this exact code snippet since if IOException is thrown, the reader is never closed and may result in hanging FileReaders which can never be garbage collected which in *nix world means you will eventually run out of file handles and your JVM just simply crashes.
Esko
Another problem is that `FileReader` implictly picks up the whatever charset happens to be the default. Also the intermediate `String` is unnecessary.
Tom Hawtin - tackline
+4  A: 

You could read your file into a List instead of a String and then convert to an array:

//Setup a BufferedReader here    
List<String> list = new ArrayList<String>();
String line = reader.readLine();
while (line != null) {
  list.add(line);
  line = reader.readLine();
}
String[] arr = list.toArray(new String[0]);
leonm
Or even leave it as an array.
Tom Hawtin - tackline
A: 

I always use this way:

String content = "";
String line;
BufferedReader reader = new BufferedReader(new FileReader(...));
while ((line = reader.readLine()) != null)
{
    content += "\n" + line;
}
// Cut of the first newline;
content = content.substring(1);
// Close the reader
reader.close();
Martijn Courteaux
FYI: Do you usually read small files with that code? I would have expected a significant performance hit with all that String concatenation... I'm don't mean to be negative, I am just curious.
Adam Paynter
Ehmm, yes... Is this method deprecated? Oh, what does FYI mean?
Martijn Courteaux
FYI = For Your Information, one of the many common acronyms used on the Web.
Esko
Why collect to a string instead of a list of strings one per each line? You usually need to do something with the collected data afterwards.
Thorbjørn Ravn Andersen
I guess the problem Adam was pointing to was that you do string concatenation += in a loop, which means you create a new String object every time (as Strings are immutable). This has quite a negative impact on performance. Use a StringBuilder (and do append()) instead of string for content.
Nicolai
Thanks for this hint. I will use this way in the futur. Now finally I get an anwser for that += operater and the new instance. Thanks
Martijn Courteaux
+13  A: 

What about using Apache Commons (Commons IO and Commons Lang)?

String[] lines = StringUtils.split(FileUtils.readFileToString(new File("...")), '\n');
romaintaz
+1 - trades one line of code for a dependency on Apache Commons IO and Lang.
duffymo
Note that this is now FileUtils.readFileToString
pimlottc
A: 

There is no built-in method in Java which can read an entire file. So you have the following options:

  • Use a non-standard library method, such as Apache Commons, see the code example in romaintaz's answer.
  • Loop around some read method (e.g. FileInputStream.read, which reads bytes, or FileReader.read, which reads chars; both read to a preallocated array). Both classes use system calls, so you'll have to speed them up with bufering (BufferedInputStream or BufferedReader) if you are reading just a small amount of data (say, less than 4096 bytes) at a time.
  • Loop around BufferedReader.readLine. There has a fundamental problem that it discards the information whether there was a '\n' at the end of the file -- so e.g. it is unable to distinguish an empty file from a file containing just a newline.

I'd use this code:

// charsetName can be null to use the default charset.
public static String readFileAsString(String fileName, String charsetName)
    throws java.io.IOException {
  java.io.InputStream is = new java.io.FileInputStream(fileName);
  try {
    final int bufsize = 4096;
    int available = is.available();
    byte data[] = new byte[available < bufsize ? bufsize : available];
    int used = 0;
    while (true) {
      if (data.length - used < bufsize) {
        byte newData[] = new byte[data.length << 1];
        System.arraycopy(data, 0, newData, 0, used);
        data = newData;
      }
      int got = is.read(data, used, data.length - used);
      if (got <= 0) break;
      used += got;
    }
    return charsetName != null ? new String(data, 0, used, charsetName)
                               : new String(data, 0, used);
  } finally {
    is.close();
  }
}

The code above has the following advantages:

  • It's correct: it reads the whole file, not discarding any byte.
  • It lets you specify the character set (encoding) the file uses.
  • It's fast (no matter how many newlines the file contains).
  • It doesn't waste memory (no matter how many newlines the file contains).
pts