2014-11-20 2 views
0

У меня есть огромный файл (более 3 ГБ), который содержит одну длинную строку в следующем формате. «1243 ​​@ 818 @ 9287 @ 543»Как обрабатывать файл с разным разделителем строк в java?

Затем данные, которые я хочу проанализировать, разделены знаком «@». Моя идея - изменить значение по умолчанию конца строки символа, используемого Java ans set "@".

Я пытаюсь использовать следующий код, используя «System.setProperty» («line.separator», «@»); но не работает, поскольку печатает полную строку и для этого теста я хотел бы как результат.

1243 
818 
9287 
543 

Как изменить разделитель строк по умолчанию на «@»?

package test; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 

public class Test { 
    public static void main(String[] args) throws FileNotFoundException, IOException { 
     System.setProperty("line.separator", "@"); 

     File testFile = new File("./Mypath/myfile"); 
     BufferedReader br = new BufferedReader(new FileReader(testFile)); 
     for(String line; (line = br.readLine()) != null;) { 
     // Process each the line. 
      System.out.println(line); 
     } 
    } 

} 

Заранее благодарим за любую помощь.

+0

'BufferedReader' не использует' line.separator'. Проверка на '\ n' и' \ r', кажется, жестко закодирована там. – Tom

ответ

1

Затем данные, которые я хочу проанализировать, разделены знаком «@». Моя идея - изменить символ конца строки по умолчанию, используемый Java ans set "@".

Я бы этого не сделал, так как это может сломаться, Бог знает, что еще это зависит от line.separator.

Что касается причин, по которым это не работает, извините, что это случай, когда RTFM не выполняется. Это то, что Javadocs для BufferedReader.readLine должен сказать:

public String readLine() 
       throws IOException 
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed. 
Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached 
Throws: IOException - If an I/O error occurs 

В API Docs для метода readLine() ясно говорит, что он ищет '\n' или '\r'. Он не говорит, что это зависит от line.separator.

Свойство line.separator предназначено только для разработки API-интерфейсов, которым необходим переносимый, независимый от платформы механизм, который идентифицирует разделители строк. Вот и все. Это системное свойство не является для управления внутренними механизмами классов ввода-вывода Java.

Я думаю, что вы слишком усложняете ситуацию.Просто делайте это по-старому, читая n-число символов (скажем 1024KB) в буфере и сканируйте каждый разделитель @. Это приводит к осложнениям, таким как обычные случаи, когда данные между разделителями «@» становятся разделенными между буферами.

Итак, я хотел бы предложить только прочитать один символ от буферного читателя (это не так уж плохо, и как правило, не ударил IO избыточно, так как буферном читатель делает ... тад ... буферизации для вас.)

Направьте каждый символ в построитель строк, и каждый раз, когда вы обнаружите разделитель «@», вы очищаете содержимое строкового конструктора до стандартного вывода или что-то в этом роде (поскольку это будет представлять собой привязку с вашего файла «@».)

Сначала попробуйте алгоритм работать правильно. Оптимизируйте позже. Ниже приведен псевдокод, нет гарантий, что ошибок компиляции нет. Вы должны быть в состоянии тривиальной плоти его в синтаксический правильной Java:

File testFile = new File("./Mypath/myfile"); 
int buffer_size = 1024 * 1024 
BufferedReader br = new BufferedReader(new FileReader(testFile), buffer_size); 

StringBuilder bld = StringBuilder(); 
int c = br.read(); 

while(c != -1){ 
    char z = (char)c; 
    if(z == '@'){ 
     System.out.println(bld); 
     if(bld.length() > 0){ 
      bld.delete(0, bld.length() - 1); 
     } 
    } else { 
     bld.append(z); 
    } 
} 
3

read()char по char и append() его до StringBuilder, пока вы не получите @

+0

Надеюсь, он не сделает это, как 'str + = currentChar;'. – Tom

+1

@ Теперь я надеюсь, что не –

+0

Я уверен, что он будет :) –

0

possbile способ сделать это (с небольшими файлами) является использование в Scanner класса:

public static void main(String[] args) throws FileNotFoundException { 
    final File file = new File("test.txt"); 
    try (final Scanner scan = new Scanner(file)) { 
     scan.useDelimiter("@"); 
     while(scan.hasNext()) { 
      System.out.println(scan.next()); 
     } 
    } 
} 

test.txt:

[email protected]@[email protected] 

Выход:

1243 
818 
9287 
543 

Но поскольку ваш файл очень большой следует избегать использования Scanner, используйте решение Jigars с BufferedReader вместо этого. Однако, если у вас есть возможность использовать файлы меньшего размера, это может стать удобным.

-2

я не уверен, если это то, что вы хотите, но вы можете прочитать всю строку в виде строки, а затем использовать метод String.split(String regex), который вернет массив строк. Этими строками будут числа между @. Затем вы можете перебирать массив и распечатывать каждый номер в строке или анализировать данные, но вы хотите.

Например:

package test; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 

public class Test { 
    public static void main(String[] args) throws FileNotFoundException, IOException { 
     System.setProperty("line.separator", "@"); 

     File testFile = new File("./Mypath/myfile"); 
     Scanner fileScanner = new Scanner(testFile); 
     String myString = fileScanner.nextLine(); 
     String[] data = myString.split("@"); 

     // Process data 
    } 
} 

Если вам необходимо преобразовать числа в целые числа, используйте Integer.parseInt(String)

Надеется, что помогли!

+1

Ничего себе, читайте в целом> 3gb-файл, а затем «скопируйте» эти данные, разделив эту строку на массив? – Tom

+0

Я знаю, что память сегодня дешевая, но чтение всего 3gb-файла в память? :) –

 Смежные вопросы

  • Нет связанных вопросов^_^