• ,

Собираем файл com.javarush.task.task18.task1825

Не могу понять, почему валидатор не пропускает.

package com.javarush.task.task18.task1825;

/* 
Собираем файл из кусочков.
Считывать с консоли имена файлов.
Каждый файл имеет имя: [someName].partN.

Например, Lion.avi.part1, Lion.avi.part2, …, Lion.avi.part37.

Имена файлов подаются в произвольном порядке. Ввод заканчивается словом «end«.
В папке, где находятся все прочтенные файлы, создать файл без суффикса [.partN].

Например, Lion.avi.

В него переписать все байты из файлов-частей используя буфер.
Файлы переписывать в строгой последовательности, сначала первую часть, потом вторую, …, в конце — последнюю.
Закрыть потоки.
*/

import java.io.*;
import java.util.TreeMap;

public class Solution {

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String fileName;
        TreeMap<Integer, String> map = new TreeMap<>();
        String regex = "\\.part\\d+?$";
        while (!"end".equals(fileName = reader.readLine())) {
            if (fileName.matches("(.+)" + regex) && new File(fileName).exists()) {
                int part = Integer.parseInt(fileName.split("part")[1]);
                map.put(part, fileName);
            }
        }
        reader.close();
        File result = new File(map.get(1).split(regex)[0]);
        if (!result.exists()) {
            result.createNewFile();
        }
        FileInputStream fis = null;
        FileOutputStream fos = new FileOutputStream(result);
        for (String s : map.values()) {
            fis = new FileInputStream(s);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            fos.write(buffer);

        }
        fos.close();


    }
}
  • ,

task18.task1825, долбаный валидатор...Что не так, если всё так?

Вдруг кто-то добрый захочет потестировать и понять что тут не так, точнее что не нравится валидатору, так как тут все так)

Усдовие задачи вот:
  1. Собираем файл
  2. Собираем файл из кусочков.
  3. Считывать с консоли имена файлов.
  4. Каждый файл имеет имя: [someName].partN.
  5. Например, Lion.avi.part1, Lion.avi.part2, …, Lion.avi.part37.
  6. Имена файлов подаются в произвольном порядке. Ввод заканчивается словом «end«.
  7. В папке, где находятся все прочтенные файлы, создать файл без суффикса [.partN].
  8. Например, Lion.avi.
  9. В него переписать все байты из файлов-частей используя буфер.
  10. Файлы переписывать в строгой последовательности, сначала первую часть, потом вторую, …, в конце — последнюю.
  11. Закрыть потоки.

Добавил сразу подробные комментарии и даже фото прикладываю.

//считываем названи
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        String file = reader.readLine(); // сразу читаем первое название файла
        boolean regFile=true; // флаг
        String regFileIs=null; // тут сохраняем первое называние файла, чтобы потом из него взять конечное, без part

        // файлы добавляем в дерево TreeSet<String> stringTreeSet, что даёт нам предварительную сортировку
        //в ней порядок будет типа этого : part1, part2, part23, part3 и т д, то есть сортирует он по первой цыфре
        TreeSet<String> stringTreeSet = new TreeSet<>();

        while (!file.equals("end")){

            //проверяем чтобы не была пустая строка и при этом файл существовал
            if(!file.equals("") && new File(file).exists()) {
                stringTreeSet.add(file); //добавляем в stringTreeSet
            }

            if(regFile){
                regFileIs = file; // сохраняем первое имя файла, на потом
               regFile=false;
           }
            file = reader.readLine(); // считываем следующую строку
        }

        // чтобы понять сколько вообще может быть part-ов, нужно понять их разброс по десятичным, сотым, тысячным и т д,
        //а это можно понять просто по длине строки если новяа строка длиннее на одну чем прошлая, значит мы перешли на следующий порядок
        // для этого в дерево TreeSet<Integer> stringLenghts я добавляю длину считанных строк (проверяя, что такой длины я ранее не добавлял)
        TreeSet<Integer> stringLenghts = new TreeSet<>();

        for(String in: stringTreeSet){
            if(!stringLenghts.contains(in.length())){
                stringLenghts.add(in.length());
            }
        }

        //теперь я создаю обычный массив  TreeSet<String>[] treeSets, чтобы разделить считанные строки по их длине
        // каково было разнообразие длин строк можно узнать из stringLenghts взяв его размер
        TreeSet<String>[] treeSets = new TreeSet[stringLenghts.size()];
        //инициализация содержимого массива новыми деревьями
        for(int x=0; x< stringLenghts.size(); x++){
            treeSets[x] = new TreeSet<String>();
        }

        //наконец тут я беру длины строк из дерева stringLenghts (а они там уже отсартированы по порядку возрастания)
        // нахожу в первом stringTreeSet дереве (куда были считаны все строки) все строки длиной in и записываю в деревья массива TreeSet<String>[] treeSets
        int x = 0;
        for(Integer in: stringLenghts) {
            for (String inS : stringTreeSet) {
                if(inS.length() == in ) treeSets[x].add(inS);
            }
            x++;
        }

        // тут я делаю итоговое называние файла
        String finishFile="";
        if(regFileIs!=null) {
        int lastIndexOf = regFileIs.lastIndexOf(".part");
            for(int indexInHold =0; indexInHold<lastIndexOf; indexInHold ++){
                finishFile+=regFileIs.charAt(indexInHold);
            }
        }

        //
        // запись содержимого файлов
        //по сути тут уже ничего особенного, прохожу по массиву TreeSet<String>[] treeSets и его внутренним TreeSet и всё записываю
        FileOutputStream outputStream = new FileOutputStream(finishFile);

        for(int d =0; d<treeSets.length; d++){

            for(Object in: treeSets[d]){
                if(in!=null) {
                    FileInputStream inputStream = new FileInputStream(in.toString());
                    byte[] bufFile = new byte[inputStream.available()];  // использую буфер как хочет валидатор
                    inputStream.read(bufFile);
                    inputStream.close();  // поток чтения закрываем

                    outputStream.write(bufFile); // записываю из буфера как опять же хочет валидатор
                }
            }
        }
        outputStream.close(); // закрываю поток записи
        //

    }