Чтобы очистить пару вещей:
FileWriter fw = new FileWriter("colon.arff", true);
В вашем объявлении FileWriter вы используете логический флаг добавления как true, который позволяет добавлять к поставляемому файлу. Я не уверен, что это действительно то, что вам нужно, учитывая тот факт, что вы хотите, чтобы записываемые в файл данные имели тот же формат, что и читаемый файл. Вы не хотели бы, чтобы что-либо было добавлено к этому файлу, что исказило бы исходный формат контента.
toWrite += line;
Выполнение конкатенации в цикле никогда не является хорошей идеей (да,Я до сих пор делаю это время от времени для простых вещей и демонстрационных целей). Простые конкатенации вне цикла - это нормально, так как компилятор использует StringBuilder в любом случае, если он считает, что это будет более выгодно. Просто лучше использовать класс StringBuilder по следующей причине:
В Java строковые объекты являются неизменяемыми, что означает, что после их создания вы не сможете его изменить. Поэтому, когда мы объединяем одну строку с другой, создается новая строка, а более старая помечается для сборщика мусора. Допустим, нам нужно объединить миллион строк. Затем мы создаем 1 миллион дополнительных строк, которые в конечном итоге будут собираться мусором.
Для решения этой проблемы используется класс StringBuilder . Он работает как изменяемый объект String. Метод StringBuilder # append () помогает избежать копирования, требуемого при конкатенации строк. Чтобы использовать StringBuilder в вашем случае, вы должны объявить построитель над циклом , а :
StringBuilder toWrite = new StringBuilder();
, а затем внутри цикла:
toWrite.append(line).append(System.lineSeparator());
Обратите внимание на дополнительные append (System.lineSeparator ()) ? Если вы хотите записать готовую строку в файл с помощью FileWriter , вам нужно добавить разрыв строки («\ n» или «\ r \ n» в зависимости от ОС), чтобы следующая строка былаНужно написать будет на новой строке в файле. В этом случае вы фактически строите строку, которая будет записана в файл с одной записью, поэтому, если добавляемая строка должна находиться в новой строке в файле, необходимо также добавить разрыв строки. Метод System.lineSeparator () возвращает зависящий от операционной системы символ (ы) перевода строки.
Приведенный ниже код выполнит то, что вы просите:
// Demo data to replace in file...
String[] newData = {"4,2,13,1,4,2,0",
"1,3,3,5,2,4,1",
"7,7,2,1,5,8,1"};
// 'Try With Resourses' is used here to auto-close the reader and writer.
try (BufferedReader reader = new BufferedReader(new FileReader("aa.txt"));
FileWriter fw = new FileWriter("colon.arff")) {
String ls = System.lineSeparator(); // The Line Break use by OS.
StringBuilder toWrite = new StringBuilder(); // A String builder object
int skip = 0; // Used for skipping old file data for placement of the new data
String line = null; // Use to hold file lines read (one at a time)
// Start reading file...
while ((line = reader.readLine()) != null) {
/* If skip is greater than 0 then read in next line and
decrement skip by 1. This is used in case the data
in file contains more rows of data than what you are
replacing. */
if (skip > 0) {
skip--;
continue;
}
// Append the file line read into the StringBuilder object
toWrite.append(line).append(ls);
// If the file line read equals "@data"
if (line.trim().equals("@data")) {
/* Append the new data to the toWrite variable here,
for example: if the new data was in a string array
named newData (see above declaration)... */
for (int i = 0; i < newData.length; i++) {
/* Perform new data Validation...
Make sure all values are string representations
of numerical data and that the 7th column of data
is no less than 0 and no more than 1. */
String[] ndParts = newData[i].split("\\s{0,},\\s{0,}"); // Split the current data row
boolean isValid = true; // flag
for (int v = 0; v < ndParts.length; v++) {
if (!ndParts[v].matches("\\d+") ||
(v == 6 && (!ndParts[v].equals("0") &&
!ndParts[v].equals("1")))) {
isValid = false;
System.err.println("Invalid numerical value supplied on Row " +
(i+1) + " in Column " + (v+1) + ". (Data: " + newData[i] + ")" +
ls + "Not writing data line to file!");
break;
}
}
/* If the current new data row is valid then append
it to the build and increment skip by 1. */
if (isValid) {
toWrite.append(newData[i]).append(ls);
skip++;
}
}
}
}
// Write the entire built string to file.
fw.write(toWrite.toString());
}
catch (FileNotFoundException ex) {
System.err.println(ex.getMessage());
}
catch (IOException ex) {
System.err.println(ex.getMessage());
}