/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.openmessaging.storage.dledger.utils; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.atomic.AtomicLong; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class IOUtils { public static final Charset DEFAULT_CHARSET = Charset.forName("utf-8"); private static Logger logger = LoggerFactory.getLogger(IOUtils.class); public static void string2File(final String str, final String fileName) throws IOException { String tmpFile = fileName + ".tmp"; string2FileNotSafe(str, tmpFile); String bakFile = fileName + ".bak"; String prevContent = file2String(fileName); if (prevContent != null) { string2FileNotSafe(prevContent, bakFile); } File file = new File(fileName); file.delete(); file = new File(tmpFile); file.renameTo(new File(fileName)); } public static void string2FileNotSafe(final String str, final String fileName) throws IOException { File file = new File(fileName); File fileParent = file.getParentFile(); if (fileParent != null) { fileParent.mkdirs(); } FileWriter fileWriter = null; try { fileWriter = new FileWriter(file); fileWriter.write(str); } catch (IOException e) { throw e; } finally { if (fileWriter != null) { fileWriter.close(); } } } public static String file2String(final String fileName) throws IOException { File file = new File(fileName); return file2String(file); } public static String file2String(final File file) throws IOException { if (file.exists()) { byte[] data = new byte[(int) file.length()]; boolean result; FileInputStream inputStream = null; try { inputStream = new FileInputStream(file); int len = inputStream.read(data); result = len == data.length; } finally { if (inputStream != null) { inputStream.close(); } } if (result) { return new String(data); } } return null; } public static String file2String(final URL url) { InputStream in = null; try { URLConnection urlConnection = url.openConnection(); urlConnection.setUseCaches(false); in = urlConnection.getInputStream(); int len = in.available(); byte[] data = new byte[len]; in.read(data, 0, len); return new String(data, "UTF-8"); } catch (Exception ignored) { } finally { if (null != in) { try { in.close(); } catch (IOException ignored) { } } } return null; } public static String properties2String(final Properties properties) { StringBuilder sb = new StringBuilder(); for (Map.Entry<Object, Object> entry : properties.entrySet()) { if (entry.getValue() != null) { sb.append(entry.getKey().toString() + "=" + entry.getValue().toString() + "\n"); } } return sb.toString(); } public static Properties string2Properties(final String str) { Properties properties = new Properties(); try { InputStream in = new ByteArrayInputStream(str.getBytes(DEFAULT_CHARSET)); properties.load(in); } catch (Exception e) { return null; } return properties; } public static Properties object2Properties(final Object object) { Properties properties = new Properties(); Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { if (!Modifier.isStatic(field.getModifiers())) { String name = field.getName(); if (!name.startsWith("this")) { Object value = null; try { field.setAccessible(true); value = field.get(object); } catch (IllegalAccessException e) { } if (value != null) { properties.setProperty(name, value.toString()); } } } } return properties; } public static void properties2Object(final Properties p, final Object object) { Method[] methods = object.getClass().getMethods(); for (Method method : methods) { String mn = method.getName(); if (mn.startsWith("set")) { try { String tmp = mn.substring(4); String first = mn.substring(3, 4); String key = first.toLowerCase() + tmp; String property = p.getProperty(key); if (property != null) { Class<?>[] pt = method.getParameterTypes(); if (pt != null && pt.length > 0) { String cn = pt[0].getSimpleName(); Object arg = null; if (cn.equals("int") || cn.equals("Integer")) { arg = Integer.parseInt(property); } else if (cn.equals("long") || cn.equals("Long")) { arg = Long.parseLong(property); } else if (cn.equals("double") || cn.equals("Double")) { arg = Double.parseDouble(property); } else if (cn.equals("boolean") || cn.equals("Boolean")) { arg = Boolean.parseBoolean(property); } else if (cn.equals("float") || cn.equals("Float")) { arg = Float.parseFloat(property); } else if (cn.equals("String")) { arg = property; } else { continue; } method.invoke(object, arg); } } } catch (Throwable ignored) { } } } } public static boolean isPropertiesEqual(final Properties p1, final Properties p2) { return p1.equals(p2); } public static List<String> getLocalInetAddress() { List<String> inetAddressList = new ArrayList<String>(); try { Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces(); while (enumeration.hasMoreElements()) { NetworkInterface networkInterface = enumeration.nextElement(); Enumeration<InetAddress> addrs = networkInterface.getInetAddresses(); while (addrs.hasMoreElements()) { inetAddressList.add(addrs.nextElement().getHostAddress()); } } } catch (SocketException e) { throw new RuntimeException("get local inet address fail", e); } return inetAddressList; } private static String localhost() { try { return InetAddress.getLocalHost().getHostAddress(); } catch (Throwable e) { try { String candidatesHost = getLocalhostByNetworkInterface(); if (candidatesHost != null) return candidatesHost; } catch (Exception ignored) { } throw new RuntimeException("InetAddress java.net.InetAddress.getLocalHost() throws UnknownHostException", e); } } //Reverse logic comparing to RemotingUtil method, consider refactor in RocketMQ 5.0 public static String getLocalhostByNetworkInterface() throws SocketException { List<String> candidatesHost = new ArrayList<String>(); Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces(); while (enumeration.hasMoreElements()) { NetworkInterface networkInterface = enumeration.nextElement(); // Workaround for docker0 bridge if ("docker0".equals(networkInterface.getName()) || !networkInterface.isUp()) { continue; } Enumeration<InetAddress> addrs = networkInterface.getInetAddresses(); while (addrs.hasMoreElements()) { InetAddress address = addrs.nextElement(); if (address.isLoopbackAddress()) { continue; } //ip4 highter priority if (address instanceof Inet6Address) { candidatesHost.add(address.getHostAddress()); continue; } return address.getHostAddress(); } } if (!candidatesHost.isEmpty()) { return candidatesHost.get(0); } return null; } public static boolean compareAndIncreaseOnly(final AtomicLong target, final long value) { long prev = target.get(); while (value > prev) { boolean updated = target.compareAndSet(prev, value); if (updated) return true; prev = target.get(); } return false; } public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + " B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } public static void deleteFile(File file) { if (!file.exists()) { return; } if (file.isFile()) { file.delete(); } else if (file.isDirectory()) { File[] files = file.listFiles(); for (File file1 : files) { deleteFile(file1); } file.delete(); } } }