2016-12-22 5 views
1

Мое требование - заменить параметр в шаблоне rtf динамическими значениями.Как обновить параметр в файле rtf с арабским текстом

Я разрабатываю приложение в Oracle adf.

Сценарий: файл шаблона находится на арабском языке с некоторыми параметрами, которые необходимо заменить во время выполнения и создать файл отправки с обновленными значениями.

Решение принято: Метод читает шаблон и генерирует другой .rtf-файл на арабском языке, заменяя параметры динамическими значениями.

Проблема: если значение параметра на арабском языке, то оно заменяет параметр каким-либо другим unicode (нечитаемым форматом), где, как и в случае английского значения параметра, оно работает как ожидалось.

Просьба помочь мне разобраться.

Ниже приведен код, создающий другой .rtf-файл.

  sendingFileName = Constants.TEMPLATE_FILE + key + ".rtf"; 
     String str = ""; 
     FileInputStream fi; 
     try { 
      fi = new FileInputStream(sendingFileName); 
      BufferedInputStream bun = new BufferedInputStream(fi); 
      StringBuilder sbb = new StringBuilder(); 
      int c = 0; 
      while ((c = bun.read()) != -1) { 
       sbb.append((char)c); 
      } 
      for (String param : (Set<String>)parameters.keySet()) { 
       String param1 = param +""; //"$" + param + "$"; 
       int index = sbb.indexOf(param1); 
       String paramValue = (String)parameters.get(param); 
       if(index>-1) { 
        sbb.replace(index, index + param1.length(), paramValue);//now run 
       } 
      } 
      str = sbb.toString(); 
      fileName = Constants.SENT_TEMPLATE + key + "_" + new Date().getTime() + ".rtf"; 
      DataOutputStream dos; 
      File _file = new File(fileName); 
      dos = new DataOutputStream(new FileOutputStream(_file)); 
      dos.writeBytes(str); 
      dos.close(); 
      fi.close(); 
     } catch (FileNotFoundException e) { 
     } catch (IOException e) { 
     } 
    } 
+0

Похоже, вам нужно установить кодировку символов для вашего файла. Посмотрите на это: http://stackoverflow.com/a/7895133/3415090 – mohammedkhan

ответ

1

JavaDoc для FileOutputStream специально говорит «FileOutputStream предназначен для записи потоков исходных байтов, таких как данные изображения. Для написания потоков символов, рассмотреть возможность использования FileWriter.» Это связано с тем, что FileOutputStream не имеет представления о кодировке символов и кодовых страницах. Вероятно, происходит то, что когда вы используете английские символы, вы остаетесь внутри стандартного «ANSII-подобного» начала почти всех кодовых страниц. Когда вы используете арабские символы, вы оба используете недопустимую кодовую страницу, а так как String хранятся как UTF-16, недопустимое количество байтов (арабские символы, скорее всего, будут многобайтными, а затем английскими).

JavaDoc из FileWriter сообщает нам, что «Конструкторы этого класса предполагают, что кодировка символов по умолчанию и размер по умолчанию байт буфера являются приемлемыми. Для того, чтобы задать эти значения самостоятельно, построить OutputStreamWriter на FileOutputStream.» Таким образом, следуя инструкции, которые нам дают, чтобы исправить вашу проблему, мы должны реализовать следующую замену переменной секции dos (с использованием StandardCharsets для краткости):

dos = new OutputStreamWriter(new FileOutputStream(_file), StandardCharsets.UTF_8); 
dos.write(str, 0, str.length()); 

Однако из-за того, как код структурирован, даже эта коррекция может столкнуться с проблемой, если вы окружаете OutputStreamWriter другим Writer, скажем, например, BufferedWriter. Вместо того, чтобы создавать одну гигантскую строку и записывать ее все сразу, подумайте о том, чтобы написать вывод итеративно. OutputStreamWriter использует внутренний буфер заданного размера для буферизации ввода в определенных обстоятельствах и дает ему огромный вход String, как это может вызвать проблемы или даже привести к IOException. В моем приведенном примере используется метод write(String, int, int), который пропускает буфер, но это обходное действие работает только до тех пор, пока вы не добавите еще одну оболочку Writer.

Вы также должны заменить BufferedInputStream bun на InputStreamReader, который является InputStream версии OutputStreamWriter. Он читает файл, используя указанную кодировку символов, вместо чтения байта файла байтом и надеется, что в данный момент это будет UTF-16. Замена будет выглядеть следующим образом:

InputStreamReader bun = InputStreamReader(fi, StandardCharsets.UTF_8); 

Если вы хотите получить дополнительную буферизацию соображений производительности вы можете обернуть это с BufferedReader.Кроме того, для входа и выхода Reader/Writer вам может потребоваться выбрать другой Charset, затем UTF-8, но поскольку я не знаю, какую кодировку файла вы используете/будете использовать, я просто по умолчанию не использовал UTF-8.

+0

Спасибо Эмили .... Попробуй то же самое и сообщите. – Mohammed