Magic8 (@NotNull VirtualFile virtualFile, @NotNull CharSequence text, byte @NotNull [] bytes, @NotNull Charset charset) { // file has BOM but the charset hasn't byte[] bom = null; try { bom = getBOMFromBytes(virtualFile.contentsToByteArray()); } catch (IOException ignored) { } if (bom != null && !CharsetToolkit.canHaveBom(charset, bom)) return Magic8.NO_WAY; // the charset has mandatory BOM (e.g. UTF-xx) but the file hasn't or has wrong byte[] mandatoryBom = CharsetToolkit.getMandatoryBom(charset); if (mandatoryBom != null && !ArrayUtil.startsWith(bytes, mandatoryBom)) return Magic8.NO_WAY; String loaded = LoadTextUtil.getTextByBinaryPresentation(bytes, charset).toString(); String separator = FileDocumentManager.getInstance().getLineSeparator(virtualFile, null); String toSave = StringUtil.convertLineSeparators(loaded, separator); LoadTextUtil.AutoDetectionReason failReason = LoadTextUtil.getCharsetAutoDetectionReason(virtualFile); if (failReason != null && StandardCharsets.UTF_8.equals(virtualFile.getCharset()) && !StandardCharsets.UTF_8.equals(charset)) { return Magic8.NO_WAY; // can't reload utf8-autodetected file in another charset } byte[] bytesToSave; try { bytesToSave = toSave.getBytes(charset); } // turned out some crazy charsets have incorrectly implemented .newEncoder() returning null catch (UnsupportedOperationException | NullPointerException e) { return Magic8.NO_WAY; } if (bom != null && !ArrayUtil.startsWith(bytesToSave, bom)) { bytesToSave = ArrayUtil.mergeArrays(bom, bytesToSave); // for 2-byte encodings String.getBytes(Charset) adds BOM automatically } return !Arrays.equals(bytesToSave, bytes) ? Magic8.NO_WAY : StringUtil.equals(loaded, text) ? Magic8.ABSOLUTELY : Magic8.WELL_IF_YOU_INSIST; }