import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author 夏天的暴风雨
*/
public class TranslateFileEncode {
final String ASC = "gb2312";
final String UTF8 = "UTF-8";
final String UTF16L = "UTF-16LE";
final String UTF16B = "UTF-16BE";
private Vector fileVector; //需要转换的文件列表
private String sourceEncode = ASC; //源文件Encode
private String dstEncode = UTF8; //目标文件Encode
private boolean hasBOM = false; //源文件是否有BOM标记
private boolean writeBOM = false; //是否向新文件的文件头写入BOM
private String fileSuffix = ".java"; //要搜索的文件类型后缀
/**
* @param args the command line arguments
*/
public String getFileEncode(File file) {
if (file.length() < 2) {
return ASC;
}
//开始查找
try {
InputStream fis = new FileInputStream(file);
if (!fis.markSupported()) {
fis = new BufferedInputStream(fis);
}
fis.mark(3);
byte[] byteBOM = new byte[3];
fis.read(byteBOM, 0, 3);
if (byteBOM[0] == (byte) 0xFF && byteBOM[1] == (byte) 0xFE) {
hasBOM = true;
fis.close();
return UTF16L;
}
if (byteBOM[0] == (byte) 0xFE && byteBOM[1] == (byte) 0xFF) {
hasBOM = true;
fis.close();
return UTF16B;
}
if (byteBOM[0] == (byte) 0xEF && byteBOM[1] == (byte) 0xBB && byteBOM[2] == (byte) 0xBF) {
hasBOM = true;
fis.close();
return UTF8;
}
fis.reset();
int read;
while ((read = fis.read()) != -1) {
if (read >= 0xF0) {
break;
}
if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK
{
break;
}
if (0xC0 <= read && read <= 0xDF) {
read = fis.read();
if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB编码内
{
continue;
} else {
break;
}
} else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错,但是几率较小
read = fis.read();
if (0x80 <= read && read <= 0xBF) {
read = fis.read();
if (0x80 <= read && read <= 0xBF) {
fis.close();
return UTF8;
} else {
break;
}
} else {
break;
}
}
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
//没有找到匹配的,默认返回本地字符集
return ASC;
}
public void TranslateFileEncode(File sourceFile) {
try {
//检查文件对象是否有效
if (sourceFile == null) {
return;
}
//将源文件改名备份,并建立目标文件
String fileName = sourceFile.getAbsolutePath();
sourceFile.renameTo(new File(fileName + "_bak"));
sourceFile = new File(fileName + "_bak");
File dstFile = new File(fileName);
dstFile.createNewFile();
//根据源文件编码读入到文件字符串
sourceEncode = getFileEncode(sourceFile);
FileInputStream fis = new FileInputStream(sourceFile);
int fileSize = fis.available();
if (hasBOM) {
if (sourceEncode == UTF16L || sourceEncode == UTF16B) {
fis.skip(2);
fileSize -= 2;
} else if (sourceEncode == UTF8) {
fis.skip(3);
fileSize -= 3;
}
}
byte[] buffer = new byte[fileSize];
fis.read(buffer);
fis.close();
String fileStr = new String(buffer, sourceEncode);
//根据目标文件编码生成对应的byte数组并写入文件
byte[] writeBytes = fileStr.getBytes(dstEncode);
FileOutputStream fos = new FileOutputStream(dstFile);
if (writeBOM) {
if (dstEncode == UTF16L) {
fos.write(0xFF);
fos.write(0xFE);
} else if (dstEncode == UTF16B) {
fos.write(0xFE);
fos.write(0xFF);
} else if (dstEncode == UTF8) {
fos.write(0xEF);
fos.write(0xBB);
fos.write(0xBF);
}
}
fos.write(writeBytes);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void addFileAsFilter(File folder) {
File files[] = folder.listFiles();
LinkedList<File> listFolder = new LinkedList<>();
for (File file : files) {
if (file.isDirectory()) {
listFolder.add(file);
} else if ((fileSuffix.equals("AllFile")) || file.getName().endsWith(fileSuffix)) {
fileVector.add(file);
}
}
File tmp;
while (!listFolder.isEmpty()) {
tmp = listFolder.removeFirst();
if (tmp.isDirectory()) {
files = tmp.listFiles();
if (files == null) {
continue;
}
for (File file : files) {
if (file.isDirectory()) {
listFolder.add(file);
} else if ((fileSuffix.equals("AllFile")) || file.getName().endsWith(fileSuffix)) {
fileVector.add(file);
}
}
}
}
}
public void createFrame(JFrame frame) {
frame.setTitle("批量转换文件编码 By:夏天的暴风雨 2016");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Dimension displaySize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.width > displaySize.width) {
frameSize.width = displaySize.width;
}
if (frameSize.height > displaySize.height) {
frameSize.height = displaySize.height;
}
int x = (displaySize.width - frameSize.width) / 2;
int y = (displaySize.height - frameSize.height) / 2;
frame.setLocation(x, y);
}
public void addComponent(JFrame frame) {
fileVector = new Vector();
MyJList jl = new MyJList(fileVector);
JScrollPane scrollPane = new JScrollPane(jl);
frame.add(scrollPane, BorderLayout.CENTER);
//窗口上面的控件
JPanel northPane = new JPanel();
frame.add(northPane, "North");
//添加文件
JButton addFile = new JButton("添加文件");
addFile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(true);
fileChooser.showDialog(fileChooser, "选择文件");
File[] selectedFiles = fileChooser.getSelectedFiles();
for (File file : selectedFiles) {
fileVector.add(file);
}
jl.updateUI();
}
});
northPane.add(addFile);
//目标编码
JLabel label = new JLabel("请选择目标编码:");
northPane.add(label);
String[] dstEndoeList = {UTF8, ASC, UTF16L, UTF16B};
JComboBox dstEncodeComboBox = new JComboBox(dstEndoeList);
northPane.add(dstEncodeComboBox);
JCheckBox checkBox = new JCheckBox("写入BOM标记");
String tipBOM = "<html>" + "<p>" + "BOM就是文件开头的文件类型标记" + "</p>"
+ "<p>" + "UTF8(BOM)---->UTF8(无BOM)可以用来清除BOM" + "</p>"
+ "<p>" + "UNICODE必须带BOM,否则读取的时候会出错" + "</p>" + "</html>";
checkBox.setToolTipText(tipBOM); //setToolTipText()不支持多行字符串,只能用HTML语言来进行多行的描述
northPane.add(checkBox);
dstEncodeComboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) //该时间会触发两次,一次为取消旧的,一次为选择新的
{
dstEncode = e.getItem().toString(); //我们用选择新的事件的Item
if (dstEncode == UTF16L || dstEncode == UTF16B) {
checkBox.setSelected(true);
checkBox.setEnabled(false);
} else {
checkBox.setEnabled(true);
if (dstEncode == ASC) {
checkBox.setSelected(false);
checkBox.setEnabled(false);
}
}
}
}
});
checkBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
writeBOM = true;
} else if (e.getStateChange() == ItemEvent.DESELECTED) {
writeBOM = false;
}
}
});
//窗口下面的控件
JPanel southPane = new JPanel();
frame.add(southPane, "South");
//选择文件夹
JButton openFolder = new JButton("搜索整个文件夹并添加");
openFolder.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fileVector.clear();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setMultiSelectionEnabled(true);
fileChooser.showDialog(fileChooser, "选择文件夹");
File[] selectedFolders = fileChooser.getSelectedFiles();
for (File file : selectedFolders) {
addFileAsFilter(file);
}
jl.updateUI();
}
});
southPane.add(openFolder);
//过滤类型
JLabel filterLabel = new JLabel("搜索类型:");
southPane.add(filterLabel);
String[] filterStr = {".java", ".html", ".txt", ".c", ".cpp", "AllFile"};
JComboBox filterComboBox = new JComboBox(filterStr);
filterComboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
fileSuffix = e.getItem().toString();
}
}
});
southPane.add(filterComboBox);
//开始转换
JButton begin = new JButton("开始转换");
begin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < fileVector.size(); i++) {
TranslateFileEncode((File) fileVector.get(i));
}
fileVector.clear();
jl.updateUI();
JOptionPane.showMessageDialog(begin, "转换完成", "提示", JOptionPane.PLAIN_MESSAGE);
}
});
southPane.add(begin);
frame.pack();
}
public static void main(String[] args) {
// TODO code application logic here
TranslateFileEncode instance = new TranslateFileEncode();
JFrame mainFrame = new JFrame();
EventQueue.invokeLater(new Runnable() {
public void run() {
instance.createFrame(mainFrame);
instance.addComponent(mainFrame);
mainFrame.setVisible(true);
}
});
}
}
----------------------------------------------------------------------------------------------------------------------------------
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JList;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author xk
*/
class MyJList extends JList implements DropTargetListener{
Vector v;
public MyJList(Vector v) {
super(v);
this.v = v;
new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
}
@Override
public void drop(DropTargetDropEvent dtde) {
try {
Transferable tr = dtde.getTransferable();
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
ArrayList list = (ArrayList) (dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor));
Iterator it = list.iterator();
while(it.hasNext()) {
File temp = (File) it.next();
if (temp.isFile())
v.add(temp);
}
this.updateUI();
dtde.dropComplete(true);
} else {
dtde.rejectDrop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void dragEnter(DropTargetDragEvent dtde) {
}
@Override
public void dragExit(DropTargetEvent dte) {
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
}