Abeer
Abeer

Reputation: 83

how to split one text into multiple text files

I have the following Text:

1
(some text)
   /
2
(some text)
       /
.
.
    /
8519
(some text)

and I want to split this text into several text-files where each file has the name of the number before the text i.e. (1.txt, 2.txt) and so on, and the content of this file will be the text.

I tried this code

BufferedReader br = new BufferedReader(new FileReader("(Path)\\doc.txt"));
try {
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();
    while (line != null) {
        sb.append(line);
        // sb.append(System.lineSeparator());
        line = br.readLine();
    }
    String str = sb.toString();
    String[] arrOfStr = str.split("/");
    for (int i = 0; i < arrOfStr.length; i++) {
        PrintWriter writer = new PrintWriter("(Path)" + arrOfStr[i].charAt(0) + ".txt", "UTF-8");
        writer.println(arrOfStr[i].substring(1));
        writer.close();
    }
    System.out.println("Done");
} finally {
    br.close();
}

this code works for files 1-9. However, things go wrong for files 10-8519 since I took the first number in the string (arrOfStr [i].charAt(0)) I know my solution is insufficient any suggestions?

Upvotes: 1

Views: 562

Answers (3)

CoolMandy
CoolMandy

Reputation: 11

Here is a quick solution for the given problem. You can test and do proper exception handling.

package practice;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

public class FileNioTest {

    public static void main(String[] args) {

        Path path = Paths.get("C:/Temp/readme.txt");

        try {
            List<String> contents = Files.readAllLines(path);
            StringBuffer sb = new StringBuffer();
            String folderName = "C:/Temp/";
            String fileName = null;
            String previousFileName = null;

            // Read from the stream
            for (String content : contents) {// for each line of content in contents
                if (content.matches("-?\\d+")) {  // check if it is a number (based on your requirement) 
                    fileName = folderName + content + ".txt";   // create a file name with path
                    if (sb != null && sb.length() > 0) {  // this means if content present to write in the file
                        writeToFile(previousFileName, sb);  // write to file
                        sb.setLength(0);              // clearing buffer
                    }
                    createFile(fileName);           // create a new file if number found in the line
                    previousFileName = fileName;    // store the name to write content in previous opened file. 
                } else {
                    sb.append(content);             // keep storing the content to write in the file.
                }
                System.out.println(content);// print the line
            }
            if (sb != null && sb.length() > 0) {
                writeToFile(fileName, sb);
                sb.setLength(0);
            }
        } catch (IOException ex) {
            ex.printStackTrace();// handle exception here
        }
    }

    private static void createFile (String fileName) {
        Path newFilePath = Paths.get(fileName);

        if (!Files.exists(newFilePath)) {
            try {
                Files.createFile(newFilePath);
            } catch (IOException e) {
                System.err.println(e);
            }
        }
    }

    private static void writeToFile (String fileName, StringBuffer sb) {
        try {
            Files.write(Paths.get(fileName), sb.toString().getBytes(), StandardOpenOption.APPEND);
        }catch (IOException e) {
             System.err.println(e);
        }
    }

}

Upvotes: 0

C.Champagne
C.Champagne

Reputation: 5489

As you mentioned, the problem is that you only take the first digit. You could enumerate the first characters until you find a non digit character ( arrOfStr[i].charAt(j) <'0' || arrOfStr[i].charAt(j) > '9' ) but it shoud be easier to user a Scanner and an appropriate regexp.

int index = new Scanner(arrOfStr[i]).useDelimiter("\\D+").nextInt();

The delimiter is precisely any group of non-digit character

Upvotes: 0

CopyJosh
CopyJosh

Reputation: 604

In addition to my comment, considering there isn't a space between the leading integer and the first word, the substring at the first space doesn't work.

This question/answer has a few options that should help, the one using regex (\d+) being the simplest one imo, and copied below.

Matcher matcher = Pattern.compile("\\d+").matcher(arrOfStr[i]);
matcher.find();
int yourNumber = Integer.valueOf(matcher.group());

Given a string find the first embedded occurrence of an integer

Upvotes: 1

Related Questions